You need to sign in or sign up before continuing.
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