On Fri, Jun 09, 2006 at 04:16:08PM -0400, Bill Sommerfeld wrote: > On Fri, 2006-06-09 at 15:52, Jonathan Adams wrote: > > > If I remember correctly, the main problems you can run into with signaling > > after dropping the lock is that there can be destruction races: > > > > thread 1 Thread 2 > > > > mutex_exit(&obj->mutex) > > --------------------------> > > mutex_enter(&obj->mutex) > > set up object for destruction > > mutex_exit(&obj->mutex) > > kmem_free(obj); > > <-------------------------- > > cv_signal(&obj->cv); > > this code may already have a race in the absence of *other* > synchronization to prevent reording like: > > --------------------------> > mutex_enter(&obj->mutex) > set up object for destruction > mutex_exit(&obj->mutex) > <-------------------------- > mutex_enter(&obj->mutex) > ... > mutex_exit(&obj->mutex) kmem_free(obj); > cv_signal(&obj->cv); > > aka "an object cannot synchronize its own destruction."
Of course; I think my example still stands, though. For example: int dropped_ref = 0; mutex_enter(&obj->mutex); if (--obj->ref == 0) dropped_ref = 1; mutex_exit(&obj->mutex); -------------------------> mutex_enter(&global); obj = obj_lookup_and_remove(); mutex_exit(&global); mutex_enter(&obj->mutex); while (obj->ref > 0) cv_wait(&obj->cv, &obj->mutex); mutex_exit(&obj->mutex); kmem_free(obj); <------------------------- if (dropped_ref) cv_signal(&obj->cv); If the signal was underneath the lock, there wouldn't be a race. Cheers, - jonathan -- Jonathan Adams, Solaris Kernel Development