+ vlc_mutex_lock( &obj->object_lock );
+}
+
+void __vlc_object_unlock( vlc_object_t *obj )
+{
+ vlc_assert_locked( &obj->object_lock );
+ vlc_mutex_unlock( &obj->object_lock );
+}
+
+/**
+ * Returns the readable end of a pipe that becomes readable whenever
+ * an object is signaled. This can be used to wait for VLC object events
+ * inside select(), poll() loops or frameworks providing an event loop.
+ *
+ * Note that the pipe will remain the same for the lifetime of the object.
+ * DO NOT close it yourself. Ever.
+ *
+ * DO NOT try to read from the pipe either: call vlc_object_wait() instead.
+ * Assuming the pipe is readable, vlc_object_wait() will not block.
+ * Also note that, as with vlc_object_wait(), there may be spurious wakeups.
+ *
+ * @param obj object that would be signaled (object lock MUST hold)
+ * @return a readable pipe descriptor, or -1 on error.
+ */
+int vlc_object_waitpipe( vlc_object_t *obj )
+{
+ int *pipes = obj->p_internals->pipes;
+ vlc_assert_locked( &obj->object_lock );
+
+ if( pipes[1] == -1 )
+ {
+ /* This can only ever happen if someone killed us without locking */
+ assert( pipes[0] == -1 );
+
+#ifndef WIN32
+ if( pipe( pipes ) )
+#else
+ if( _pipe( pipes, 1, _O_BINARY ) )
+#endif
+ return -1;
+ }
+
+ return pipes[0];
+}
+
+
+/**
+ * Waits for the object to be signaled (using vlc_object_signal()).
+ * If the object already has a signal pending, this function will return
+ * immediately. It is asserted that the caller holds the object lock.
+ *
+ * @return true if the object is dying and should terminate.
+ */
+vlc_bool_t __vlc_object_wait( vlc_object_t *obj )
+{
+ vlc_assert_locked( &obj->object_lock );
+
+ int fd = obj->p_internals->pipes[0];
+ if( fd != -1 )
+ {
+ if( read( fd, &(char){ 0 }, 1 ) == 0 )
+ {
+ close( fd );
+ obj->p_internals->pipes[1] = -1;
+ }
+ return obj->b_die;
+ }
+
+ vlc_cond_wait( &obj->object_wait, &obj->object_lock );
+ return obj->b_die;