Thanks, that's now commited in git :-) !

  
https://git.gnome.org/browse/libxml2/commit/?id=620a70615e68b30db1a80a993180a41dc24f12b9

Daniel

On Tue, Mar 03, 2015 at 09:55:30AM +0000, Steven Nairn wrote:
> Hi,
> 
> After recently upgrading to 2.9.2 for use in our (multi-threaded)
> program we started to experience occasional hangs on Windows (the
> other platforms were fine).
> 
> Attaching to the hung process with gdb showed that all the threads
> were waiting on the xmlDictMutex xmlRMutex. The count field of the
> xmlRMutex was zero, which indicated that the mutex should not have
> been locked. However, the cs field showed that the CriticalSection was
> locked and was held by a thread that had completed. So, that thread
> had locked the mutex but not unlocked it.
> 
> Eventually the problem was tracked down to the maintenance of the
> count field. The relevant code fragments (with non-Windows stuff
> removed) are:
> ----
> typedef struct _xmlRMutex {
>     CRITICAL_SECTION cs;
>     unsigned int count;
> } *xmlRMutexPtr;
> 
> void xmlRMutexLock(xmlRMutexPtr tok)
> {
>     EnterCriticalSection(&tok->cs);
>     tok->count++;
> }
> 
> void xmlRMutexUnlock(xmlRMutexPtr tok)
> {
>     if (tok->count > 0) {
>         LeaveCriticalSection(&tok->cs);
>         tok->count--;
>     }
> }
> ----
> 
> So, when locking the mutex the count field is incremented inside the
> critical section but when unlocking the count field is decremented
> outside the critical section. The increment/decrement is not atomic so
> if one thread is locking the mutex while another is unlocking it the
> count field might not be updated properly. This is what was happening
> in our case, leading to a call to xmlRMutexUnlock not calling
> LeaveCriticalSection.
> 
> The fix is simple. When unlocking the xmlRMutex decrement the count
> field before leaving the critical section. That is:
> ----
> void xmlRMutexUnlock(xmlRMutexPtr tok)
> {
>     if (tok->count > 0) {
>         tok->count--;
>         LeaveCriticalSection(&tok->cs);
>     }
> }
> ----
> 
> This problem was introduced in commit id
> 8854e4631844eac8dbae10cc32904f27d5268af7 for bug 737851. Prior to the
> change the Windows CriticalSections were definitely not being left
> properly when xmlRMutexes were used recursively. However, at least in
> the way we use libxml2, that problem was masked since xmlRMutexes were
> not used recursively.
> 
> I've added a comment to the bug in bugzilla.
> 
> Cheers,
> Steve
> _______________________________________________
> xml mailing list, project page  http://xmlsoft.org/
> xml@gnome.org
> https://mail.gnome.org/mailman/listinfo/xml

-- 
Daniel Veillard      | Open Source and Standards, Red Hat
veill...@redhat.com  | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
http://veillard.com/ | virtualization library  http://libvirt.org/
_______________________________________________
xml mailing list, project page  http://xmlsoft.org/
xml@gnome.org
https://mail.gnome.org/mailman/listinfo/xml

Reply via email to