Commit 0146fbe3 authored by Max Kellermann's avatar Max Kellermann Committed by Eric Wong

use the pthread API in notify.c

This patch rewrites notify.c to use the pthread API, namely pthread_mutex and pthread_cond. This is a lot cheaper and easier than the pipe() hack. git-svn-id: https://svn.musicpd.org/mpd/trunk@7280 09075e82-0dd4-0310-85a5-a0d7c8717e4f
parent 38e0dafc
......@@ -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(&notify->mutex, NULL);
if (ret != 0)
return ret;
ret = pthread_cond_init(&notify->cond, NULL);
if (ret != 0) {
pthread_mutex_destroy(&notify->mutex);
return ret;
}
notify->pending = 0;
return 0;
}
void notifyWait(Notify *notify)
void notifyEnter(Notify *notify)
{
char buffer[64];
pthread_mutex_lock(&notify->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(&notify->mutex);
}
void notifyWait(Notify *notify)
{
if (!notify->pending)
pthread_cond_wait(&notify->cond, &notify->mutex);
notify->pending = 0;
}
void notifySignal(Notify *notify)
{
char buffer = 0;
notify->pending = 1;
pthread_cond_signal(&notify->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(&notify->mutex);
notifySignal(notify);
pthread_mutex_unlock(&notify->mutex);
}
......@@ -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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment