/*
* Empire - A multi-player, client/server Internet based war game.
- * Copyright (C) 1986-2007, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ * Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
* Ken Stevens, Steve McClure
*
* This program is free software; you can redistribute it and/or modify
* ---
*
* pthread.c: Interface from Empire threads to POSIX threads
- *
+ *
* Known contributors to this file:
* Sasha Mikheev
* Steve McClure, 1998
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
-#if !defined(_WIN32)
#include <sys/time.h>
#include <unistd.h>
-#endif
#include "misc.h"
#include "empthread.h"
}
-/*
- * prio can be used for setting scheeduling policy but...
- * it seems to be optional in POSIX threads and Solaris
- * for example just ignores it.
- * More then that priority is not needed even in lwp threads.
- */
empth_t *
-empth_create(int prio, void (*entry)(void *), int size, int flags,
+empth_create(void (*entry)(void *), int size, int flags,
char *name, void *ud)
{
pthread_t t;
return pthread_getspecific(ctx_key);
}
+char *
+empth_name(empth_t *thread)
+{
+ return thread->name;
+}
+
+void
+empth_set_name(empth_t *thread, char *name)
+{
+ if (thread->name)
+ free(thread->name);
+ thread->name = strdup(name);
+}
+
void
empth_exit(void)
{
pthread_kill(a->id, SIGALRM);
}
-void
-empth_select(int fd, int flags)
+int
+empth_select(int fd, int flags, struct timeval *tv)
{
-
fd_set readmask;
fd_set writemask;
- struct timeval tv;
int n;
+ int res = 0;
pthread_mutex_unlock(&mtx_ctxsw);
empth_status("%s select on %d",
flags == EMPTH_FD_READ ? "read" : "write", fd);
- while (1) {
- tv.tv_sec = 1000000;
- tv.tv_usec = 0;
- FD_ZERO(&readmask);
- FD_ZERO(&writemask);
-
- switch (flags) {
- case EMPTH_FD_READ:
- FD_SET(fd, &readmask);
- break;
- case EMPTH_FD_WRITE:
- FD_SET(fd, &writemask);
- break;
- default:
- logerror("bad flag %d passed to empth_select", flags);
- empth_exit();
- }
+ FD_ZERO(&readmask);
+ FD_ZERO(&writemask);
+
+ switch (flags) {
+ case EMPTH_FD_READ:
+ FD_SET(fd, &readmask);
+ break;
+ case EMPTH_FD_WRITE:
+ FD_SET(fd, &writemask);
+ break;
+ default:
+ CANT_REACH();
+ errno = EINVAL;
+ res = -1;
+ goto done;
+ }
- n = select(fd + 1, &readmask, &writemask, (fd_set *) 0, &tv);
+ n = select(fd + 1, &readmask, &writemask, (fd_set *) 0, tv);
- if (n < 0) {
- if (errno == EINTR) {
- /* go handle the signal */
- empth_status("select broken by signal");
- goto done;
- return;
- }
- /* strange but we dont get EINTR on select broken by signal */
+ if (n < 0) {
+ if (errno == EINTR) /* go handle the signal */
+ empth_status("select broken by signal");
+ else
empth_status("select failed (%s)", strerror(errno));
- goto done;
- return;
- }
-
- if (flags == EMPTH_FD_READ && FD_ISSET(fd, &readmask)) {
- empth_status("input ready");
- break;
- }
- if (flags == EMPTH_FD_WRITE && FD_ISSET(fd, &writemask)) {
- empth_status("output ready");
- break;
- }
+ res = -1;
+ } else if (n == 0) {
+ empth_status("select timed out");
+ res = 0;
+ } else if (flags == EMPTH_FD_READ && FD_ISSET(fd, &readmask)) {
+ empth_status("input ready");
+ res = 1;
+ } else if (flags == EMPTH_FD_WRITE && FD_ISSET(fd, &writemask)) {
+ empth_status("output ready");
+ res = 1;
}
- done:
+done:
pthread_mutex_lock(&mtx_ctxsw);
empth_restorectx();
+ return res;
}
static void