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
Irrlicht, pthreads and Segmentation Faults [solved]
Irrlicht, pthreads and Segmentation Faults [solved]
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:
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
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
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.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
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();"vitek wrote: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.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
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);
}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#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
Code: Select all
glBindTexture(GL_TEXTURE_2D, TextureName);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.
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:
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.