/*
* Create a new thread.
* ENTRY is the entry point. It will be called with argument UD.
+ * If it returns, the thread terminates as if it called empth_exit().
* Thread stack is at least SIZE bytes.
* FLAGS should be the same as were passed to empth_init(), or zero.
* NAME is the thread's name, it is used for logging and debugging.
*/
void empth_yield(void);
-/*
- * Terminate THREAD.
- * THREAD will not be scheduled again. Instead, it will terminate as
- * if it executed empth_exit(). It is unspecified when exactly that
- * happens.
- * THREAD must not be the current thread.
- * Naive use of this function almost always leads to resource leaks.
- * Terminating a thread that may hold locks is not a good idea.
- */
-void empth_terminate(empth_t *thread);
-
/*
* Put current thread to sleep until file descriptor FD is ready for I/O.
* If FLAGS & EMPTH_FD_READ, wake up if FD is ready for input.
/* The user data passed in at create time. */
void *pvUserData;
- /* True if this thread has been killed. */
- BOOL bKilled;
-
/* The entry function for the thread. */
void (*pfnEntry) (void *);
empth_t *pThread = TlsGetValue(dwTLSIndex);
- if (pThread->bKilled) {
- if (!pThread->bMainThread) {
- TlsSetValue(dwTLSIndex, NULL);
- loc_FreeThreadInfo(pThread);
- _endthread();
- }
- }
-
hWaitObjects[0] = hThreadMutex;
hWaitObjects[1] = hWaitObject;
loc_RunThisThread(NULL);
}
-/************************
- * empth_terminate
- *
- * Kill off the thread.
- */
-void
-empth_terminate(empth_t *pThread)
-{
- loc_debug("killing thread %s", pThread->szName);
- pThread->bKilled = TRUE;
-
- SetEvent(pThread->hThreadEvent);
-}
-
/************************
* empth_select
*
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
-
#include "misc.h"
#include "empthread.h"
#include "prototypes.h"
-#define EMPTH_KILLED 1
-#define EMPTH_INTR 2
-
struct empth_t {
char *name; /* thread name */
void *ud; /* user data */
- int state; /* my state */
+ int wakeup;
void (*ep)(void *); /* entry point */
pthread_t id; /* thread id */
};
ctx->ep = 0;
ctx->ud = 0;
ctx->id = pthread_self();
- ctx->state = 0;
+ ctx->wakeup = 0;
pthread_setspecific(ctx_key, ctx);
pthread_mutex_lock(&mtx_ctxsw);
logerror("pthreads initialized");
}
ctx->name = strdup(name);
ctx->ud = ud;
- ctx->state = 0;
+ ctx->wakeup = 0;
ctx->ep = entry;
eno = pthread_attr_init(&attr);
ctx_ptr = pthread_getspecific(ctx_key);
*udata = ctx_ptr->ud;
- if (ctx_ptr->state == EMPTH_KILLED) {
- empth_status("i am dead");
- empth_exit();
- }
- ctx_ptr->state = 0;
+ ctx_ptr->wakeup = 0;
empth_status("context restored");
}
empth_restorectx();
}
-void
-empth_terminate(empth_t *a)
-{
- empth_status("killing thread %s", a->name);
- a->state = EMPTH_KILLED;
- pthread_kill(a->id, SIGALRM);
-}
-
int
empth_select(int fd, int flags, struct timeval *timeout)
{
{
/*
* Nothing to do --- we handle this signal just to let
- * empth_wakeup() and empth_terminate() interrupt system calls.
+ * empth_wakeup() interrupt system calls.
*/
}
empth_wakeup(empth_t *a)
{
empth_status("waking up thread %s", a->name);
- if (a->state == 0)
- a->state = EMPTH_INTR;
+ a->wakeup = 1;
pthread_kill(a->id, SIGALRM);
}
tv.tv_sec = until - time(NULL);
tv.tv_usec = 0;
res = select(0, NULL, NULL, NULL, &tv);
- } while (res < 0 && ctx->state == 0);
+ } while (res < 0 && !ctx->wakeup);
empth_status("sleep done. Waiting for lock");
pthread_mutex_lock(&mtx_ctxsw);
empth_restorectx();