Irrlicht, pthreads and Segmentation Faults [solved]

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
jack
Posts: 13
Joined: Tue Oct 30, 2007 7:48 pm

Irrlicht, pthreads and Segmentation Faults [solved]

Post by jack »

Hi,

I have a multi-threaded application using irrlicht. When I try to access an Irrlicht object in a thread within which it wasn't created I get a segfault.

For instance, a global ITexture* being initialised by a call to device->addTexture(...) in my main threads main() function. (I've tried non-static and static versions of this variable).

After this (and other initialisations) my main thread spawns a bunch of processes which poll for network data, send network data and captures webcam frames. My main thread then loops and draws the game.

When I try to access this ITexture in the child processes I get a segfault. But it's not every access that seg faults. I am able to lock the ITexture, but attempts to unlock it will segfault.

I've had other people look at my code and they have said it is thread-safe, and the error is within Irrlicht.

Anyone got any ideas?

Thanks
Last edited by jack on Tue Dec 04, 2007 2:34 pm, edited 1 time in total.
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

Unfortunately, Irrlicht isn't threadsafe internally. I think you'll need to implement your own mutexing to protect it.
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
jack
Posts: 13
Joined: Tue Oct 30, 2007 7:48 pm

Post by jack »

I am using mutexes. :p Its when I access an irrlicht method by a thread that didn't instantiate the object I'm calling it with that I get a segfault. :(
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

Its when I access an irrlicht method by a thread that didn't instantiate the object I'm calling it with that I get a segfault
That isn't enough. If you create an object that is shared across threads, you need to syncronize access to that object from all threads that access it, even the thread that created it.
jack
Posts: 13
Joined: Tue Oct 30, 2007 7:48 pm

Post by jack »

vitek wrote:
Its when I access an irrlicht method by a thread that didn't instantiate the object I'm calling it with that I get a segfault
That isn't enough. If you create an object that is shared across threads, you need to syncronize access to that object from all threads that access it, even the thread that created it.
I am using mutexes everytime I access the object. The spawned thread function is shown below, the line that segfaults is the call to "webcam->unlock();"

Code: Select all

void* sendFrame(void* ptr)
{
    pthread_mutex_lock(&webcam_lock);

        // Get a new frame
        webcam->takePicture();

        // Initialise buffers
        source_buffer = webcam->dumpPicture();
        u8* dest_buffer = (u8*) webcamTexture->lock();

        // Copy pixel data from the webcam buffer to the texture buffer
        memcpy(dest_buffer, source_buffer, WEBCAM_TOTALSIZE);

        // Unlock the webcamTexture for drawing
        webcamTexture->unlock();

    pthread_mutex_unlock(&webcam_lock);
}
A backtrace from gdb shows:
#0 0xb7ee5276 in glBindTexture () from /usr/lib/libGL.so.1
#1 0x080eaa9f in irr::video::COpenGLTexture::copyTexture (this=0x8fc72f0, newTexture=false) at COpenGLTexture.cpp:238
#2 0x080eae6e in irr::video::COpenGLTexture::unlock (this=0x8fc72f0) at COpenGLTexture.cpp:345
#3 0x08064fc3 in sendFrame (ptr=0x0) at main.cpp:781
#4 0xb7cbc46b in start_thread () from /lib/tls/i686/cmov/libpthread.so.0
#5 0xb7b1c6de in clone () from /lib/tls/i686/cmov/libc.so.6
I find this really odd because the first call to webcam->lock is fine, so the object can be accessed correctly by this spawned thread. The eventual segfault is in the glBindTexture() function which is simply called by the line

Code: Select all

glBindTexture(GL_TEXTURE_2D, TextureName);
Any ideas?
jack
Posts: 13
Joined: Tue Oct 30, 2007 7:48 pm

Post by jack »

With some help from IRC people, it turns out that openGL is not thread safe.

Everything to do with openGL should be done in the same thread. So I change my main thread to do the lock/unlock operators to get the pointer which I need to write the pixel values into. This pointer is a global variable which I access in my frame grabbing thread to write pixel values. I implement my own mutexing for the pointer to the texture buffer.
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

You could do some kind of doublebuffering, storing the latest camera picture into one buffer, while reading from the other one when copying into the texture. With proper locking on those user-space memory areas you should get proper separation of picture and texture handling with increased throughput.
Post Reply