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

Reply via email to