mirror of
https://github.com/darlinghq/darling-libkqueue.git
synced 2025-02-15 01:37:31 +00:00
Removed unused/unneeded evt_loop implementation
git-svn-id: svn://svn.code.sf.net/p/libkqueue/code/trunk@501 fb4e3144-bc1c-4b72-a658-5bcd248dd7f7
This commit is contained in:
parent
699bb19e76
commit
e04070c63b
@ -1,269 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Marius Zwicker <marius@mlba-team.de>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "../common/private.h"
|
||||
|
||||
/*
|
||||
* Conditionals on windows
|
||||
*/
|
||||
#if TARGET_WIN_VISTA
|
||||
// These conditions are supported using Windows Vista and up only. We need a XP compatible workaround here
|
||||
|
||||
# define pthread_cond_init(c,x) InitializeConditionVariable((c))
|
||||
# define pthread_cond_destroy(c)
|
||||
# define pthread_cond_wait(c,m) SleepConditionVariableCS((c),(m), INFINITE)
|
||||
# define pthread_cond_broadcast(c) WakeAllConditionVariable((c));
|
||||
# define pthread_cond_signal(c) WakeConditionVariable((c));
|
||||
|
||||
#else
|
||||
|
||||
typedef struct {
|
||||
int unused;
|
||||
} pthread_condattr_t;
|
||||
|
||||
/* Credits for this pthread_cond_t implementation on windows go to
|
||||
the authors of http://www.cs.wustl.edu/~schmidt/win32-cv-1.html:
|
||||
Douglas C. Schmidt and Irfan Pyarali
|
||||
Department of Computer Science
|
||||
Washington University, St. Louis, Missouri
|
||||
|
||||
Please note that this implementation is not a fully featured posix condition implementation
|
||||
but only usable for our purposes as it allows only one thread calling cond_wait at a time.
|
||||
*/
|
||||
|
||||
int
|
||||
pthread_cond_init (pthread_cond_t *cv,
|
||||
const pthread_condattr_t * attr)
|
||||
{
|
||||
cv->waiters_count_ = 0;
|
||||
|
||||
// Init the second mutex
|
||||
InitializeCriticalSection(&cv->waiters_count_lock_);
|
||||
|
||||
// Create an auto-reset event.
|
||||
cv->events_[SIGNAL] = CreateEvent (NULL, // no security
|
||||
FALSE, // auto-reset event
|
||||
FALSE, // non-signaled initially
|
||||
NULL); // unnamed
|
||||
|
||||
// Create a manual-reset event.
|
||||
cv->events_[BROADCAST] = CreateEvent (NULL, // no security
|
||||
TRUE, // manual-reset
|
||||
FALSE, // non-signaled initially
|
||||
NULL); // unnamed
|
||||
|
||||
return cv->events_[SIGNAL] == 0 || cv->events_[BROADCAST] == 0 ;
|
||||
}
|
||||
|
||||
int pthread_cond_timedwait(pthread_cond_t *cv,
|
||||
pthread_mutex_t *external_mutex, const struct timespec* timeout)
|
||||
{
|
||||
DWORD timeout_ms, rv;
|
||||
int last_waiter = 0;
|
||||
|
||||
/* Convert timeout to milliseconds */
|
||||
/* NOTE: loss of precision for timeout values less than 1ms */
|
||||
if (timeout == NULL) {
|
||||
timeout_ms = INFINITE;
|
||||
} else {
|
||||
timeout_ms = 0;
|
||||
if (timeout->tv_sec > 0)
|
||||
timeout_ms += ((DWORD)timeout->tv_sec) / 1000;
|
||||
if (timeout->tv_sec > 0)
|
||||
timeout_ms += timeout->tv_nsec / 1000000;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Avoid race conditions.
|
||||
EnterCriticalSection (&cv->waiters_count_lock_);
|
||||
cv->waiters_count_++;
|
||||
LeaveCriticalSection (&cv->waiters_count_lock_);
|
||||
|
||||
// It's ok to release the <external_mutex> here since Win32
|
||||
// manual-reset events maintain state when used with
|
||||
// <SetEvent>. This avoids the "lost wakeup" bug...
|
||||
LeaveCriticalSection (external_mutex);
|
||||
|
||||
// Wait for either event to become signaled due to <pthread_cond_signal>
|
||||
// being called or <pthread_cond_broadcast> being called.
|
||||
rv = WaitForMultipleObjects (2, cv->events_, FALSE, timeout_ms);
|
||||
if( rv == WAIT_TIMEOUT) {
|
||||
return EVT_TIMEDOUT;
|
||||
} else if(rv == WAIT_FAILED) {
|
||||
dbg_lasterror("cond_timedwait failed");
|
||||
return EVT_ERR;
|
||||
}
|
||||
|
||||
EnterCriticalSection (&cv->waiters_count_lock_);
|
||||
cv->waiters_count_--;
|
||||
last_waiter =
|
||||
rv == WAIT_OBJECT_0 + BROADCAST
|
||||
&& cv->waiters_count_ == 0;
|
||||
LeaveCriticalSection (&cv->waiters_count_lock_);
|
||||
|
||||
// Some thread called <pthread_cond_broadcast>.
|
||||
if (last_waiter)
|
||||
// We're the last waiter to be notified or to stop waiting, so
|
||||
// reset the manual event.
|
||||
ResetEvent (cv->events_[BROADCAST]);
|
||||
|
||||
// Reacquire the <external_mutex>.
|
||||
EnterCriticalSection (external_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pthread_cond_wait (pthread_cond_t *cv,
|
||||
pthread_mutex_t *external_mutex)
|
||||
{
|
||||
return pthread_cond_timedwait(cv, external_mutex, NULL);
|
||||
}
|
||||
|
||||
int
|
||||
pthread_cond_signal (pthread_cond_t *cv)
|
||||
{
|
||||
int have_waiters = 0;
|
||||
|
||||
// Avoid race conditions.
|
||||
EnterCriticalSection (&cv->waiters_count_lock_);
|
||||
have_waiters = cv->waiters_count_ > 0;
|
||||
LeaveCriticalSection (&cv->waiters_count_lock_);
|
||||
|
||||
if (have_waiters)
|
||||
SetEvent (cv->events_[SIGNAL]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
pthread_cond_destroy(pthread_cond_t *cv)
|
||||
{
|
||||
CloseHandle(cv->events_[SIGNAL]);
|
||||
CloseHandle(cv->events_[BROADCAST]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Event loop implementation
|
||||
*/
|
||||
|
||||
void evt_init(evt_loop_t t){
|
||||
assert(t);
|
||||
pthread_mutex_init(&t->access, NULL);
|
||||
pthread_cond_init(&t->cond, NULL);
|
||||
t->used = TRUE;
|
||||
}
|
||||
|
||||
evt_loop_t evt_create(){
|
||||
evt_loop_t neu = (evt_loop_t)malloc(sizeof(struct evt_loop_s));
|
||||
assert(neu);
|
||||
memset(neu,0,sizeof(struct evt_loop_s));
|
||||
|
||||
evt_init(neu);
|
||||
|
||||
return neu;
|
||||
}
|
||||
|
||||
int evt_signal(evt_loop_t l, int type, void* data){
|
||||
// create new item
|
||||
evt_event_t i = (evt_event_t)malloc(sizeof(struct evt_event_s));
|
||||
|
||||
assert(l);
|
||||
|
||||
if (i == NULL)
|
||||
return -1; // creation failed
|
||||
i->type = type; // link with the given event type
|
||||
i->data = data;
|
||||
i->next = NULL;
|
||||
|
||||
pthread_mutex_lock(&l->access);
|
||||
if (l->last != NULL)
|
||||
l->last->next = i;
|
||||
l->last = i;
|
||||
if (l->first == NULL) { // if this item is first one, signal waiting getitem call
|
||||
l->first = i;
|
||||
pthread_cond_signal(&l->cond);
|
||||
}
|
||||
pthread_mutex_unlock(&l->access);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int evt_run(evt_loop_t l, evt_event_t evt, int max_ct, const struct timespec* timeout){
|
||||
evt_event_t curr = NULL;
|
||||
|
||||
assert(l);
|
||||
assert(evt);
|
||||
assert(max_ct > 0);
|
||||
|
||||
pthread_mutex_lock(&l->access);
|
||||
while(1){
|
||||
// get item from list, if available
|
||||
if (l->first == NULL) {
|
||||
if( pthread_cond_timedwait(&l->cond, &l->access, timeout) == EVT_TIMEDOUT ) // no item available, wait for it
|
||||
return EVT_TIMEDOUT;
|
||||
|
||||
// in this case we can be sure to hold the mutex again
|
||||
continue;
|
||||
}
|
||||
curr = l->first;
|
||||
l->first = curr->next; // remove item
|
||||
if (l->first == NULL)
|
||||
l->last = NULL; // this was the last item
|
||||
pthread_mutex_unlock(&l->access);
|
||||
|
||||
assert(curr);
|
||||
// TODO: Real event array support
|
||||
// return the current event
|
||||
memcpy(&(evt[0]), curr, sizeof(struct evt_event_s));
|
||||
free(curr);
|
||||
return 1;
|
||||
|
||||
pthread_mutex_lock(&l->access);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void evt_destroy(evt_loop_t l){
|
||||
evt_event_t i = NULL, curr = NULL;
|
||||
|
||||
assert(l);
|
||||
|
||||
if (l->used == FALSE)
|
||||
return;
|
||||
|
||||
// delete all waiting items
|
||||
i = l->first;
|
||||
while (i != NULL) {
|
||||
curr = i;
|
||||
i = i->next;
|
||||
free(curr);
|
||||
}
|
||||
|
||||
// reset list
|
||||
l->first = NULL;
|
||||
l->last = NULL;
|
||||
|
||||
pthread_mutex_destroy(&l->access);
|
||||
pthread_cond_destroy(&l->cond);
|
||||
|
||||
free(l);
|
||||
}
|
@ -1,119 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Marius Zwicker <marius@mlba-team.de>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef KQUEUE_WINDOWS_EVENTLOOP_H
|
||||
#define KQUEUE_WINDOWS_EVENTLOOP_H
|
||||
|
||||
// some condition variable typedefs
|
||||
#if TARGET_WIN_VISTA
|
||||
// These conditions are supported using Windows Vista and up only. We need a XP compatible workaround here
|
||||
|
||||
typedef CONDITION_VARIABLE pthread_cond_t;
|
||||
|
||||
#else
|
||||
|
||||
typedef struct {
|
||||
u_int waiters_count_;
|
||||
// Count of the number of waiters.
|
||||
|
||||
CRITICAL_SECTION waiters_count_lock_;
|
||||
// Serialize access to <waiters_count_>.
|
||||
|
||||
#define SIGNAL 0
|
||||
#define BROADCAST 1
|
||||
#define MAX_EVENTS 2
|
||||
|
||||
HANDLE events_[MAX_EVENTS];
|
||||
// Signal and broadcast event HANDLEs.
|
||||
} pthread_cond_t;
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// A single event item
|
||||
//
|
||||
typedef struct evt_event_s {
|
||||
int type;
|
||||
void* data;
|
||||
struct evt_event_s* next;
|
||||
}* evt_event_t;
|
||||
|
||||
#define EVT_EVENT_INITIALIZER { 0, NULL, NULL }
|
||||
|
||||
//
|
||||
// An event loop, normally you have one loop per thread
|
||||
//
|
||||
typedef struct evt_loop_s {
|
||||
int id;
|
||||
void* data;
|
||||
evt_event_t first;
|
||||
evt_event_t last;
|
||||
pthread_mutex_t access;
|
||||
pthread_cond_t cond;
|
||||
unsigned char used;
|
||||
}* evt_loop_t;
|
||||
|
||||
//
|
||||
// The different event types
|
||||
//
|
||||
enum evt_type {
|
||||
EVT_WAKEUP =0, /* Simply wake the thread, the callback will know what to do */
|
||||
EVT_EXIT =1, /* Immediately exit the event loop */
|
||||
EVT_CUSTOM =2 /* Some custom event */
|
||||
};
|
||||
|
||||
//
|
||||
// Flags describing the return values of evt_run
|
||||
//
|
||||
enum evt_flags {
|
||||
EVT_ERR = -3, /* An error occured */
|
||||
EVT_TIMEDOUT = -5, /* Timeout elapsed before receiving an event */
|
||||
};
|
||||
|
||||
//
|
||||
// Creates a new event loop
|
||||
//
|
||||
evt_loop_t evt_create();
|
||||
|
||||
//
|
||||
// Initializes an existing eventloop (as if it was new)
|
||||
//
|
||||
void evt_init(evt_loop_t t);
|
||||
|
||||
//
|
||||
// Destroys the given event loop, make sure
|
||||
// that evt-run returned before. This will
|
||||
// erase all pending events as well
|
||||
//
|
||||
void evt_destroy(evt_loop_t l);
|
||||
|
||||
//
|
||||
// Sends an event of type type with the given data
|
||||
// to the given event loop
|
||||
//
|
||||
int evt_signal(evt_loop_t l, int type, void* data);
|
||||
|
||||
//
|
||||
// Executes the given event loop.
|
||||
// Will return in two casees only:
|
||||
// - The timeout expired (return value EVT_TIMEDOUT)
|
||||
// - An event was returned (return value corresponds to the number of events returned)
|
||||
// evt will contain the returned events as an array, with max_ct events maximum
|
||||
//
|
||||
int evt_run(evt_loop_t l, evt_event_t evt, int max_ct, const struct timespec* timeout);
|
||||
|
||||
#endif /* KQUEUE_WINDOWS_EVENTLOOP_H */
|
@ -102,7 +102,7 @@ windows_kqueue_init(struct kqueue *kq)
|
||||
#endif
|
||||
|
||||
if(filter_register_all(kq) < 0) {
|
||||
evt_destroy(kq->kq_loop);
|
||||
CloseHandle(kq->kq_iocp);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@ -112,7 +112,7 @@ windows_kqueue_init(struct kqueue *kq)
|
||||
void
|
||||
windows_kqueue_free(struct kqueue *kq)
|
||||
{
|
||||
evt_destroy(kq->kq_loop);
|
||||
CloseHandle(kq->kq_iocp);
|
||||
free(kq);
|
||||
}
|
||||
|
||||
@ -150,27 +150,6 @@ windows_kevent_wait(struct kqueue *kq, int no, const struct timespec *timeout)
|
||||
dbg_lasterror("GetQueuedCompletionStatus");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#if DEADWOOD
|
||||
DWORD rv;
|
||||
|
||||
/* Wait for an event */
|
||||
dbg_printf("waiting for %u events (timeout=%u ms)", kq->kq_filt_count, (unsigned int)timeout_ms);
|
||||
rv = evt_run(kq->kq_loop, pending_events, MAX_KEVENT, timeout);
|
||||
switch (rv) {
|
||||
case EVT_TIMEDOUT:
|
||||
dbg_puts("no events within the given timeout");
|
||||
retval = 0;
|
||||
break;
|
||||
|
||||
case EVT_ERR:
|
||||
dbg_lasterror("WaitForSingleEvent()");
|
||||
retval = -1;
|
||||
|
||||
default:
|
||||
retval = rv;
|
||||
}
|
||||
#endif
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
@ -64,7 +64,6 @@
|
||||
#define KQUEUE_PLATFORM_SPECIFIC \
|
||||
HANDLE kq_iocp; \
|
||||
HANDLE kq_synthetic_event; \
|
||||
evt_loop_t kq_loop; \
|
||||
struct filter *kq_filt_ref[EVFILT_SYSCOUNT]; \
|
||||
size_t kq_filt_count
|
||||
|
||||
@ -163,6 +162,5 @@ typedef CRITICAL_SECTION pthread_rwlock_t;
|
||||
#define pthread_rwlock_unlock _cs_unlock
|
||||
#define pthread_rwlock_init(x,y) _cs_init((x))
|
||||
|
||||
#include "event_loop.h"
|
||||
|
||||
#endif /* ! _KQUEUE_WINDOWS_PLATFORM_H */
|
||||
|
Loading…
x
Reference in New Issue
Block a user