Philip Guenther wrote: > On Thu, Mar 20, 2008 at 3:01 PM, Tvrvk Edwin <[EMAIL PROTECTED]> wrote: > >> ClamAV has changed to call fork() after creating its local socket. >> This causes weird behaviours when communicating on the socket [1] >> >> If fork() is called before creating the socket() it works. >> >> Is it safe to create a socket, fork(), and then call pthread_create() >> and read from the socket? >> > > The relevant passages from the Single Unix Specification were cited in > the thread on the FreeBSD list. The rule is that if the process had > more than one thread when fork() was called, then the child can only > call async-signal safe functions until it calls execle(), execve(), > _exit(), or _Exit(). pthread_create() is not async-signal safe, so to > answer your question to you have to look at the state of the process > before the call to fork(). > > The underlying problem is that after the fork(), the child's state may > include such things as mutexes which are locked by threads that no > longer exist and mutexes that have non-existent threads in their > 'waiting' queue. pthread_create() probably needs to allocate memory > for the thread's handle and stack; if some other thread was in > malloc() at the time of the fork(), then the heap is probably both > locked and inconsistent in the child. >
Thanks for the detailed explanation, however threads are created only after fork(). fork() is used to daemonize the process. > > >> It seems not to work, the thread gets stuck in pthread_mutex_lock(), and >> it is not woken up even after the mutex is free. Moving fork() before >> the socket avoids this. >> Is this intended behaviour or a bug? >> > > If there was more than one thread in the process when fork() was > called, then it's a bug in clamav. Period. > > (If there were any threads before the fork() that may have been > blocked on the mutex, then the behavior is completely predictable, as > the mutex's wait queue has an entry for a thread that no longer > exists.) > > No threads are created before calling fork(), it only parses its configuration files, loads the database, and creates the socket. pthread_create is called after the fork(), in the child. pthread_create is called while a mutex is locked, could that be a problem? It calls pthread_mutex_lock()/unlock() before fork(), but even if I temporarely comment out those, I am still seeing the weird behavior. Thanks, --Edwin