diff options
Diffstat (limited to '')
-rw-r--r-- | src/notify.c | 54 | ||||
-rw-r--r-- | src/notify.h | 45 |
2 files changed, 66 insertions, 33 deletions
diff --git a/src/notify.c b/src/notify.c index 4eda79391..5d53b231d 100644 --- a/src/notify.c +++ b/src/notify.c @@ -17,32 +17,52 @@ */ #include "notify.h" -#include "os_compat.h" -#include "log.h" -#include "utils.h" -void notifyInit(Notify *notify) +int notifyInit(Notify *notify) { - if (pipe(notify->fds) < 0) - FATAL("Couldn't open pipe: %s", strerror(errno)); - if (set_nonblocking(notify->fds[1]) < 0) - FATAL("Couldn't set non-blocking on notify fd: %s", - strerror(errno)); + int ret; + + ret = pthread_mutex_init(¬ify->mutex, NULL); + if (ret != 0) + return ret; + + ret = pthread_cond_init(¬ify->cond, NULL); + if (ret != 0) { + pthread_mutex_destroy(¬ify->mutex); + return ret; + } + + notify->pending = 0; + + return 0; } -void notifyWait(Notify *notify) +void notifyEnter(Notify *notify) { - char buffer[64]; + pthread_mutex_lock(¬ify->mutex); +} - if (read(notify->fds[0], buffer, sizeof(buffer)) < 0) - FATAL("error reading from pipe: %s\n", strerror(errno)); +void notifyLeave(Notify *notify) +{ + pthread_mutex_unlock(¬ify->mutex); +} + +void notifyWait(Notify *notify) +{ + if (!notify->pending) + pthread_cond_wait(¬ify->cond, ¬ify->mutex); + notify->pending = 0; } void notifySignal(Notify *notify) { - char buffer = 0; + notify->pending = 1; + pthread_cond_signal(¬ify->cond); +} - if (write(notify->fds[1], &buffer, sizeof(buffer)) < 0 && - errno != EAGAIN && errno != EINTR) - FATAL("error writing to pipe: %s\n", strerror(errno)); +void notifySignalSync(Notify *notify) +{ + pthread_mutex_lock(¬ify->mutex); + notifySignal(notify); + pthread_mutex_unlock(¬ify->mutex); } diff --git a/src/notify.h b/src/notify.h index 9f1a1961b..f79518f8f 100644 --- a/src/notify.h +++ b/src/notify.h @@ -19,29 +19,42 @@ #ifndef NOTIFY_H #define NOTIFY_H -/* - * This library implements inter-process signalling using blocking - * read() on an anonymous pipe. As a side effect, the read() system - * call has the same signal interruption behaviour as the old sleep - * function. - * - * As soon as mpd uses threading instead of fork()/shm, we can replace - * this library with a pthread_cond object. - * - * This code is experimental and carries a lot of overhead. Still, it - * uses less resources than the old polling code with a fixed sleep - * time. - * - */ +#include "os_compat.h" typedef struct _Notify { - int fds[2]; + pthread_mutex_t mutex; + pthread_cond_t cond; + int pending; } Notify; -void notifyInit(Notify *notify); +int notifyInit(Notify *notify); + +/** + * The thread which shall be notified by this object must call this + * function before any notifyWait() invocation. It locks the mutex. + */ +void notifyEnter(Notify *notify); + +/** + * Neutralize notifyLeave(). + */ +void notifyLeave(Notify *notify); +/** + * Wait for a notification. Return immediately if we have already + * been notified since we last returned from notifyWait(). + */ void notifyWait(Notify *notify); +/** + * Notify the thread. This function never blocks. + */ void notifySignal(Notify *notify); +/** + * Notify the thread synchonously, i.e. wait until it has received the + * notification. + */ +void notifySignalSync(Notify *notify); + #endif |