[haiku-development] Re: Creating a new thread

  • From: Joseph Groover <looncraz@xxxxxxxxxxx>
  • To: haiku-development@xxxxxxxxxxxxx
  • Date: Sat, 05 May 2012 11:11:34 -0500

On 5/5/2012 07:40, David Rawson Couzelis wrote:
My Haiku application will download information from the Internet. To
prevent the GUI from locking up I need to do the downloading in a
separate thread. (correct?)

I think I need to create a subclass of BLooper and override the "Run"
method. To control it, I send it messages.

Is a BLooper subclass the best way to make a new thread by using the
Haiku API?

Thank you.

The best way is with spawn_thread and resume_thread:

I haven't tested this code, but it'll probably work (barring the occassional tyypo...)

class ObjectWithThread{

                            if (fThread >= 0)
kill_thread(fThread); // can cause problems, but that is another story

                // actual thread function:

            static status_t    Thread(void * _pointer)
                    // do some work, case _pointer to an object you need
                    // for simplicity's sake, I normally do this:

                   return B_OK;

// because threads are static functions, the can't access members of the // object directly, so I normally just have the thread call into the object
            void        ThreadFunction()
// do some work, you can access all members of the object normally

    // To create the thread:

                    void SomeCallYouWantToBeAsync()
// you will want to do some locking for while the thread is running // if the thread will not persist (in which case you should use a semaphore
                        // to direct activity in the thread...
fThread = spawn_thread(&Thread, "SuperDuperFancyThread", B_LOW_PRIORITY, this);

// The last argument, 'this', is the pointer given to the static Thread function.

                        // Your thread is NOT running, yet.

if (fThread >= 0) // 0 is technically valid - but would be used up in the kernel...
// the thread is now running and will be scheduled to perform its work now // Any work you do here will occur while the thread is running, and locking
                            // conflicts should be taken into account
// basically: don't hold a lock the ThreadFunction uses and then wait for the // thread to complete... that would freeze both the app's thread and your // SuperDuperFancyThread... which would not be cool...

                thread_id                fThread;        // member variable


In the above quick-n-dirty example, the thread will exit after doing whatever it is to do, I've found the easiest way to keep a thread hanging around with as little issues as possible dealing with send_data and others is as follows:

Create a member variable BLocker fSemaphore, then make the following changes:

In the constructor of the object, spawn and resume the thread.

In SomeCallYouWantToBeAsync() just do the following:

// prepare for allowing your ThreadFunction to know what its next task is...
// the thread will be trying to gain the lock, and will safely wait until it has it before
        // doing any more work.



            // do your work!
// I normally make a list of the argument to SomeCallYouWantToBeAsync // and have a sub-loop iterate through each of them here so you get all
            // the work done every time...
// the semaphore trick can, sometimes, stall because two threads call // fSemaphore.Unlock() at the same time, you will want to protect that // with another BLocker (which is just a semaphore in sheep's clothing).



Good luck!

I'm sure someone will tell you my way is bad ;-) We all do things a little differently ;-)

--The loon

Other related posts: