[PATCH 09/30] Preparing timer.c and timer.c for windows support


Michael Schonberg <mschonberg@...>
 

These files are required by the Avis bridge as Avis does not provide
native timer support. The changes include changing pthread_xxx calls to
wthread_xxx calls, and implementing macros for socketpair and setting
nonblocking because windows does not support socketpair() and uses a
slightly differfent call for setting non-blocking on a socket.

Signed-off-by: Mike Schonberg <mschonberg@nyx.com>
---
common/c_cpp/src/c/linux/port.h | 7 ++
common/c_cpp/src/c/timers.c | 176 +++++++++++++++++++--------------------
common/c_cpp/src/c/timers.h | 2 +-
3 files changed, 92 insertions(+), 93 deletions(-)

diff --git a/common/c_cpp/src/c/linux/port.h b/common/c_cpp/src/c/linux/port.h
index 1a00b25..f8b711c 100644
--- a/common/c_cpp/src/c/linux/port.h
+++ b/common/c_cpp/src/c/linux/port.h
@@ -40,6 +40,7 @@ extern "C"
#include <sys/resource.h>
#include <sys/time.h>
#include <sys/times.h>
+#include <sys/socket.h>
#include <netinet/in.h>
#include <semaphore.h>
#include <dirent.h>
@@ -94,9 +95,15 @@ typedef long long int w_i64_t;

int wsem_timedwait (wsem_t* sem, unsigned int ts);

+/* Windows does not support AF_UNIX sockets, socketpairs, etc */
+#define wsocketpair(dom, type, prot, pair) (socketpair((dom),(type),(prot),(pair)))
+#define wsetnonblock(s) (fcntl((s), F_SETFL, O_NONBLOCK))
+
#define CPU_AFFINITY_SET cpu_set_t

/* User pthreads for linux */
+#define INVALID_THREAD (-1)
+
#define wthread_mutex_t pthread_mutex_t
#define wthread_mutex_init pthread_mutex_init
#define wthread_mutex_unlock pthread_mutex_unlock
diff --git a/common/c_cpp/src/c/timers.c b/common/c_cpp/src/c/timers.c
index 5901643..b5680c8 100644
--- a/common/c_cpp/src/c/timers.c
+++ b/common/c_cpp/src/c/timers.c
@@ -19,11 +19,10 @@
* 02110-1301 USA
*/

+#include "port.h"
#include "timers.h"

-#include <sys/socket.h>
#include <sys/types.h>
-#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
@@ -59,41 +58,33 @@ RB_GENERATE_STATIC(orderedTimeRBTree_, timerImpl_, mTreeEntry, orderedTimeRBTree

typedef struct timerHeapImpl_
{
- pthread_mutex_t mLock;
- pthread_t mDispatchThread;
+ wthread_mutex_t mLock;
+ wthread_t mDispatchThread;
orderedTimeRBTree mTimeTree;
int mSockPair[2];
- pthread_mutex_t mEndingLock;
- pthread_cond_t mEndingCond;
+ wthread_mutex_t mEndingLock;
+ wthread_cond_t mEndingCond;
int mEnding;
} timerHeapImpl;


int createTimerHeap (timerHeap* heap)
{
- pthread_mutexattr_t attr;
+ wthread_mutexattr_t attr;
timerHeapImpl* heapImpl = (timerHeapImpl*)calloc (1, sizeof (timerHeapImpl));
if (heapImpl == NULL)
return -1;

- pthread_mutexattr_init (&attr);
- pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE_NP);
+ wthread_mutexattr_init (&attr);
+ wthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE_NP);

/* Need to make the lock recursive as it should be possible to remove timers
in the call back */
- if (pthread_mutex_init (&heapImpl->mLock, &attr) != 0)
- {
- free (heapImpl);
- return -1;
- }
+ wthread_mutex_init (&heapImpl->mLock, &attr);

- if (pthread_mutex_init (&heapImpl->mEndingLock, NULL) != 0)
- {
- free (heapImpl);
- return -1;
- }
+ wthread_mutex_init (&heapImpl->mEndingLock, NULL);

- if (pthread_cond_init (&heapImpl->mEndingCond, NULL) != 0)
+ if (wthread_cond_init (&heapImpl->mEndingCond, NULL) != 0)
{
free (heapImpl);
return -1;
@@ -101,14 +92,14 @@ int createTimerHeap (timerHeap* heap)

RB_INIT (&heapImpl->mTimeTree);

- if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, heapImpl->mSockPair) == -1)
+ if (wsocketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, heapImpl->mSockPair) == -1)
{
free (heapImpl);
return -1;
}

- fcntl (heapImpl->mSockPair[0], F_SETFL, O_NONBLOCK);
- fcntl (heapImpl->mSockPair[1], F_SETFL, O_NONBLOCK);
+ wsetnonblock(heapImpl->mSockPair[0]);
+ wsetnonblock(heapImpl->mSockPair[1]);

*heap = heapImpl;
return 0;
@@ -126,42 +117,42 @@ void* dispatchEntry (void *closure)
timerImpl* ele = NULL;
struct timeval timeout, now, *timeptr;

- pthread_mutex_lock (&heap->mLock);
+ wthread_mutex_lock (&heap->mLock);
ele = RB_MIN (orderedTimeRBTree_, &heap->mTimeTree);

while (1)
{
if (ele==NULL)
timeptr = NULL;
- else
- {
- timeptr = &timeout;
- gettimeofday (&now, NULL);
- if (!timercmp(&ele->mTimeout, &now, >))
- timerclear (&timeout);
- else
- timersub(&ele->mTimeout, &now, &timeout);
- }
- pthread_mutex_unlock (&heap->mLock);
-
- /* Sit on Select as it has the best resolution */
- FD_ZERO(&wakeUpDes);
- FD_SET(heap->mSockPair[0], &wakeUpDes);
+ else
+ {
+ timeptr = &timeout;
+ gettimeofday (&now, NULL);
+ if (!timercmp(&ele->mTimeout, &now, >))
+ timerclear (&timeout);
+ else
+ timersub(&ele->mTimeout, &now, &timeout);
+ }
+ wthread_mutex_unlock (&heap->mLock);
+
+ /* Sit on Select as it has the best resolution */
+ FD_ZERO(&wakeUpDes);
+ FD_SET(heap->mSockPair[0], &wakeUpDes);

- selectReturn = select(heap->mSockPair[0] + 1, &wakeUpDes, NULL, NULL, timeptr);
+ selectReturn = select(heap->mSockPair[0] + 1, &wakeUpDes, NULL, NULL, timeptr);

- pthread_mutex_lock (&heap->mLock);
- if (selectReturn == -1)
- {
+ wthread_mutex_lock (&heap->mLock);
+ if (selectReturn == -1)
+ {
if (errno != EINTR)
- perror("select()");
- }
- else if (selectReturn)
- {
- int numRead = 0;
- do
- {
- numRead = read(heap->mSockPair[0], &buff, sizeof (buff));
+ perror("select()");
+ }
+ else if (selectReturn)
+ {
+ int numRead = 0;
+ do
+ {
+ numRead = read(heap->mSockPair[0], &buff, sizeof (buff));
if (numRead < 0)
{
if (errno == EINTR)
@@ -169,33 +160,33 @@ void* dispatchEntry (void *closure)
}
if (buff == 'd')
goto endLoop;
- }
- while (numRead > 0);
- }
-
- /* Dispatch all expired timers */
- ele = RB_MIN (orderedTimeRBTree_, &heap->mTimeTree);
- /* It is possible that this could be empty if the timer was removed before timeout */
- if (ele != NULL)
- {
+ }
+ while (numRead > 0);
+ }
+
+ /* Dispatch all expired timers */
+ ele = RB_MIN (orderedTimeRBTree_, &heap->mTimeTree);
+ /* It is possible that this could be empty if the timer was removed before timeout */
+ if (ele != NULL)
+ {
gettimeofday (&now, NULL);
- while (!timercmp(&ele->mTimeout, &now, >))
- {
- RB_REMOVE (orderedTimeRBTree_, &heap->mTimeTree, ele);
- ele->mCb (ele, ele->mClosure);
- ele = RB_MIN (orderedTimeRBTree_, &heap->mTimeTree);
- /* No timers left so break */
- if (ele == NULL)
- break;
+ while (!timercmp(&ele->mTimeout, &now, >))
+ {
+ RB_REMOVE (orderedTimeRBTree_, &heap->mTimeTree, ele);
+ ele->mCb (ele, ele->mClosure);
+ ele = RB_MIN (orderedTimeRBTree_, &heap->mTimeTree);
+ /* No timers left so break */
+ if (ele == NULL)
+ break;
}
- }
+ }
}
endLoop:
- pthread_mutex_unlock (&heap->mLock);
- pthread_mutex_lock (&heap->mEndingLock);
+ wthread_mutex_unlock (&heap->mLock);
+ wthread_mutex_lock (&heap->mEndingLock);
heap->mEnding = 1;
- pthread_cond_signal (&heap->mEndingCond);
- pthread_mutex_unlock (&heap->mEndingLock);
+ wthread_cond_signal (&heap->mEndingCond);
+ wthread_mutex_unlock (&heap->mEndingLock);
}
return NULL;
}
@@ -206,14 +197,15 @@ int startDispatchTimerHeap (timerHeap heap)
return -1;
{
timerHeapImpl* heapImpl = (timerHeapImpl*)heap;
- return pthread_create(&heapImpl->mDispatchThread, NULL, dispatchEntry, (void*)heapImpl);
+ return wthread_create(&heapImpl->mDispatchThread, NULL, dispatchEntry, (void*)heapImpl);
}
}

-pthread_t timerHeapGetTid (timerHeap heap)
+wthread_t timerHeapGetTid (timerHeap heap)
{
if (heap == NULL)
- return -1;
+ return INVALID_THREAD;
+
{
timerHeapImpl* heapImpl = (timerHeapImpl*)heap;
return heapImpl->mDispatchThread;
@@ -240,13 +232,13 @@ writeagain:
}
}

- pthread_mutex_lock (&heapImpl->mEndingLock);
+ wthread_mutex_lock (&heapImpl->mEndingLock);
while (heapImpl->mEnding == 0)
{
- pthread_cond_wait (&heapImpl->mEndingCond,
+ wthread_cond_wait (&heapImpl->mEndingCond,
&heapImpl->mEndingLock);
}
- pthread_mutex_unlock (&heapImpl->mEndingLock);
+ wthread_mutex_unlock (&heapImpl->mEndingLock);
free (heapImpl);
}
return 0;
@@ -273,7 +265,7 @@ int createTimer (timerElement* timer, timerHeap heap, timerFireCb cb, struct tim
ele->mCb = cb;
ele->mClosure = closure;

- pthread_mutex_lock (&heapImpl->mLock);
+ wthread_mutex_lock (&heapImpl->mLock);
nextTimeOut = RB_MIN (orderedTimeRBTree_, &heapImpl->mTimeTree);
if (nextTimeOut == NULL)
kickPipe = 1;
@@ -286,18 +278,18 @@ int createTimer (timerElement* timer, timerHeap heap, timerFireCb cb, struct tim
{
writeagain:
if (write (heapImpl->mSockPair[1], "w", 1) < 0)
- {
- if ((errno == EINTR) || (errno == EAGAIN))
- goto writeagain;
- else
- {
- perror ("write()");
- pthread_mutex_unlock (&heapImpl->mLock);
- return -1;
- }
- }
+ {
+ if ((errno == EINTR) || (errno == EAGAIN))
+ goto writeagain;
+ else
+ {
+ perror ("write()");
+ wthread_mutex_unlock (&heapImpl->mLock);
+ return -1;
+ }
+ }
}
- pthread_mutex_unlock (&heapImpl->mLock);
+ wthread_mutex_unlock (&heapImpl->mLock);

*timer = ele;
}
@@ -313,10 +305,10 @@ int destroyTimer (timerHeap heap, timerElement timer)
timerImpl* ele = (timerImpl*)timer;
timerHeapImpl* heapImpl = (timerHeapImpl*)heap;

- pthread_mutex_lock (&heapImpl->mLock);
+ wthread_mutex_lock (&heapImpl->mLock);
if (RB_FIND (orderedTimeRBTree_, &heapImpl->mTimeTree, ele))
RB_REMOVE (orderedTimeRBTree_, &heapImpl->mTimeTree, ele);
- pthread_mutex_unlock (&heapImpl->mLock);
+ wthread_mutex_unlock (&heapImpl->mLock);
free (ele);
}
return 0;
diff --git a/common/c_cpp/src/c/timers.h b/common/c_cpp/src/c/timers.h
index 38a3732..4f4fb4d 100644
--- a/common/c_cpp/src/c/timers.h
+++ b/common/c_cpp/src/c/timers.h
@@ -31,7 +31,7 @@ typedef void (*timerFireCb)(timerElement timer, void* mClosure);

int createTimerHeap (timerHeap* heap);
int startDispatchTimerHeap (timerHeap heap);
-pthread_t timerHeapGetTid (timerHeap heap);
+wthread_t timerHeapGetTid (timerHeap heap);
int destroyHeap (timerHeap heap);

int createTimer (timerElement* timer, timerHeap heap, timerFireCb cb, struct timeval* timeout, void* closure);
--
1.7.7.6