[kaffe] CVS kaffe (guilhem): Fixlet for jthreadedRecvFrom (pthread)

Kaffe CVS cvs-commits at kaffe.org
Tue Apr 12 08:02:03 PDT 2005


PatchSet 5673 
Date: 2005/04/12 14:57:16
Author: guilhem
Branch: HEAD
Tag: (none) 
Log:
Fixlet for jthreadedRecvFrom (pthread)

2005-04-11  Guilhem Lavaux  <guilhem at kaffe.org>
        Nektarios K. Papadopoulos <npapadop at inaccessnetworks.com>

        * kaffe/kaffevm/systems/unix-pthreads/syscalls.c
        (jthreadedRecvFrom): Fixed parameter to waitForTimeout.

Members: 
	ChangeLog:1.3839->1.3840 
	kaffe/kaffevm/systems/unix-pthreads/syscalls.c:INITIAL->1.31 

Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.3839 kaffe/ChangeLog:1.3840
--- kaffe/ChangeLog:1.3839	Mon Apr 11 17:43:41 2005
+++ kaffe/ChangeLog	Tue Apr 12 14:57:16 2005
@@ -1,3 +1,9 @@
+2005-04-11  Guilhem Lavaux  <guilhem at kaffe.org>
+	Nektarios K. Papadopoulos <npapadop at inaccessnetworks.com>
+	
+	* kaffe/kaffevm/systems/unix-pthreads/syscalls.c
+	(jthreadedRecvFrom): Fixed parameter to waitForTimeout.
+
 2005-04-11  Rei Odaira  <ray at is.s.u-tokyo.ac.jp>
 
 	* kaffe/kaffevm/jit3/icode.c
===================================================================
Checking out kaffe/kaffe/kaffevm/systems/unix-pthreads/syscalls.c
RCS:  /home/cvs/kaffe/kaffe/kaffe/kaffevm/systems/unix-pthreads/syscalls.c,v
VERS: 1.31
***************
--- /dev/null	Sun Aug  4 19:57:58 2002
+++ kaffe/kaffe/kaffevm/systems/unix-pthreads/syscalls.c	Tue Apr 12 15:02:03 2005
@@ -0,0 +1,915 @@
+/*
+ * syscalls.c
+ *
+ * Copyright (c) 1996, 1997
+ *      Transvirtual Technologies, Inc.  All rights reserved.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file.
+ */
+
+#include "config.h"
+#include "debug.h"
+#include "config-std.h"
+#include "config-mem.h"
+#include "config-io.h"
+#include "config-signal.h"
+#include "config-net.h"
+#include "gtypes.h"
+#include "jsyscall.h"
+#include "jsignal.h"
+#include "nets.h"
+#include "lock-impl.h"
+
+#if defined(HAVE_SYS_WAIT_H)
+#include <sys/wait.h>
+#endif
+
+/*
+ * various building blocks for timeout system call functions
+ */
+#define SET_DEADLINE(deadline, timeout) 		\
+	if (timeout != NOTIMEOUT) {			\
+		deadline = timeout + currentTime();	\
+	}
+
+#define BREAK_IF_LATE(deadline, timeout)		\
+	if (timeout != NOTIMEOUT) {			\
+		if (currentTime() >= deadline) {	\
+			errno = ETIMEDOUT;		\
+			break;				\
+		}					\
+	}
+
+#define IGNORE_EINTR(r)					\
+	if (r == -1 && errno == EINTR) {		\
+		continue;				\
+	}
+
+#define SET_RETURN(r)					\
+	if (r == -1) {					\
+		r = errno;				\
+	} 
+
+#define SET_RETURN_OUT(r, out, ret)			\
+	if (r == -1) {					\
+		r = errno;				\
+	} else {					\
+		*out = ret;				\
+		r = 0;					\
+	}
+
+static 
+int
+waitForTimeout(int fd, int timeout){
+	fd_set rset;
+	struct timeval tv;
+	int ret;
+
+	FD_ZERO(&rset);
+	FD_SET(fd,&rset);
+	tv.tv_sec = timeout / 1000;
+	tv.tv_usec = (timeout % 1000) * 1000;
+
+	jthread_current()->interrupting = 0;
+	if (timeout == NOTIMEOUT) 
+		ret = select(fd+1,&rset,NULL,NULL,NULL);
+	else	
+		ret = select(fd+1,&rset,NULL,NULL,&tv);
+
+	if (ret == 0) 
+		errno = ETIMEDOUT;
+	else if (ret == -1)
+	{
+		errno = EINTR;
+		jthread_current()->interrupting = 1;
+	}
+
+	return (ret);
+}
+
+/* These two functions would need to be merged some time later.
+ */
+static
+int waitForWritable(int fd, int timeout)
+{
+	fd_set wset;
+	struct timeval tv;
+	int ret;
+
+	FD_ZERO(&wset);
+        FD_SET(fd,&wset);
+        tv.tv_sec = timeout / 1000;
+	tv.tv_usec = (timeout % 1000) * 1000;
+
+	jthread_current()->interrupting = 0;
+        if (timeout == NOTIMEOUT)
+		ret = select(fd+1,NULL,&wset,NULL,NULL);
+	else
+		ret = select(fd+1,NULL,&wset,NULL,&tv);
+
+	if (ret == 0)
+		errno = ETIMEDOUT;
+	else if (ret == -1)
+	{
+		errno = EINTR;
+		jthread_current()->interrupting = 1;
+	}
+
+	return (ret);
+}
+
+static
+jlong
+currentTime(void)
+{
+    struct timeval tm;
+    gettimeofday(&tm, NULL);
+    return (((jlong)tm.tv_sec * 1000L) + ((jlong)tm.tv_usec / 1000L));
+}
+
+/*
+ * Threaded socket create.
+ */
+static int
+jthreadedSocket(int af, int type, int proto, int *out)
+{
+        int r;
+
+        r = socket(af, type, proto);
+        if (r == -1) {
+                r = errno;
+        } else {
+                *out = r;
+                r = 0;
+        }
+        return (r);
+}
+
+static int
+jthreadedOpen(const char* path, int flags, int mode, int *out)
+{
+        int r;
+
+        /* Cygnus WinNT requires this */
+        r = open(path, flags|O_BINARY, mode);
+        if (r == -1) {
+                r = errno;
+        } else {
+                *out = r;
+                r = 0;
+        }
+        return (r);
+}
+
+static int
+jthreadedClose(int fd)
+{
+	int rc = 0;
+
+	if (close(fd) == -1) {
+		rc = errno;
+	}
+	return (rc);
+}
+
+static int
+jthreadedListen(int fd, int l)
+{
+	int rc = 0;
+
+	if (listen(fd, l) == -1) {
+		rc = errno;
+	}
+	return (rc);
+}
+
+static int
+jthreadedKill(int pid, int sig)
+{
+	int rc = 0;
+
+	if (kill(pid, sig) == -1) {
+		rc = errno;
+	}
+	return (rc);
+}
+
+static int
+jthreadedBind(int fd, struct sockaddr *addr, int namelen)
+{
+	int rc = 0;
+
+	if (bind(fd, addr, (socklen_t)namelen) == -1) {
+		rc = errno;
+	}
+	return (rc);
+}
+
+static int
+jthreadedLSeek(int fd, off_t offset, int whence, off_t *out)
+{
+	int rc = 0;
+
+	*out = lseek(fd, offset, whence);
+	if (*out == -1) {
+		rc = errno;
+	}
+	return (rc);
+}
+
+static int
+jthreadedFStat(int fd, struct stat *sb)
+{
+	int rc = 0;
+
+	if (fstat(fd, sb) == -1) {
+		rc = errno;
+	}
+	return (rc);
+}
+
+static int
+jthreadedStat(const char* path, struct stat *sb)
+{
+	int rc = 0;
+
+	if (stat(path, sb) == -1) {
+		rc = errno;
+	}
+	return (rc);
+}
+
+static int
+jthreadedFTruncate(int fd, off_t new_size)
+{
+	int rc = 0;
+	
+	if (ftruncate(fd, new_size) == -1) {
+		rc = errno;
+	}
+	return (rc);
+}
+
+static int
+jthreadedFSync(int fd)
+{
+	int rc = 0;
+	
+	if (fsync(fd) == -1) {
+		rc = errno;
+	}
+	return (rc);
+}
+
+static int
+jthreadedMkdir(const char *path, int mode)
+{
+	int rc = 0;
+
+	if (mkdir(path, (mode_t)mode) == -1) {
+		rc = errno;
+	}
+	return (rc);
+}
+
+static int
+jthreadedRmdir(const char *path)
+{
+	int rc = 0;
+
+	if (rmdir(path) == -1) {
+		rc = errno;
+	}
+	return (rc);
+}
+
+static int
+jthreadedRename(const char *path1, const char *path2)
+{
+	int rc = 0;
+
+	if (rename(path1, path2) == -1) {
+		rc = errno;
+	}
+	return (rc);
+}
+
+static int
+jthreadedRemove(const char *entry)
+{
+	int rc = 0;
+
+	if (remove(entry) == -1) {
+		rc = errno;
+	}
+	return (rc);
+}
+
+static int     
+jthreadedSendto(int a, const void* b, size_t c, int d, const struct sockaddr* e,
+		int f, ssize_t *out)
+{
+	int rc = 0;
+
+	*out = e ? sendto(a, b, c, d, e, (socklen_t)f) : send(a, b, c, d);
+	if (*out == -1) {
+		rc = errno;
+	}
+	return (rc);
+}
+
+static int
+jthreadedSetSockOpt(int a, int b, int c, const void* d, int e)
+{
+	int rc = 0;
+
+	if (setsockopt(a, b, c, d, (socklen_t)e) == -1) {
+		rc = errno;
+	}
+	return (rc);
+}
+
+static int
+jthreadedGetSockOpt(int a, int b, int c, void* d, int* e)
+{
+	int rc = 0;
+
+	if (getsockopt(a, b, c, d, e) == -1) {
+		rc = errno;
+	}
+	return (rc);
+}
+
+static int
+jthreadedGetSockName(int a, struct sockaddr* b, int* c)
+{
+	int rc = 0;
+
+	if (getsockname(a, b, c) == -1) {
+		rc = errno;
+	}
+	return (rc);
+}
+
+static int
+jthreadedGetPeerName(int a, struct sockaddr* b, int* c)
+{
+	int rc = 0;
+
+	if (getpeername(a, b, c) == -1) {
+		rc = errno;
+	}
+	return (rc);
+}
+
+static int
+jthreadedGetHostByName(const char *host, struct hostent** out)
+{
+	int rc = 0;
+
+	/* NB: this will block the whole process while we're looking up
+	 * a name.  However, gethostbyname is extremely async-signal-unsafe,
+	 * and hence we have no other choice.  Now I understand why old 
+	 * Netscapes blocked when looking up a name.  
+	 *
+	 * In a UNIXy system, a possible solution is to spawn a process
+	 * for lookups, which I think is what NS eventually did.
+	 */
+	*out = gethostbyname(host);
+	if (*out == 0) {
+		rc = h_errno;
+		if (rc == 0) {
+			*out = (void*)-1;
+			rc = errno;
+		}
+	}
+	return (rc);
+}
+
+static int
+jthreadedGetHostByAddr(const char *host, size_t l, int t, struct hostent** out)
+{
+	int rc = 0;
+
+	/* NB: same comment as for jthreadedGetHostByName applies here */
+	*out = gethostbyaddr(host, l, t);
+	if (*out == 0) {
+		rc = h_errno;
+		if (rc == 0) {
+			*out = (void*)-1;
+			rc = errno;
+		}
+	}
+	return (rc);
+}
+
+static int
+jthreadedSelect(int a, fd_set* b, fd_set* c, fd_set* d, 
+		struct timeval* e, int* out)
+{
+	int rc = 0;
+
+	if ((*out = select(a, b, c, d, e)) == -1) {
+		rc = errno;
+	}
+	return (rc);
+}
+
+/*
+ * Threaded socket connect.
+ */
+static int
+jthreadedConnect(int fd, struct sockaddr* addr, int len, int timeout)
+{
+	int r;
+	jlong deadline = 0;
+	int inProgress = 0;
+
+	SET_DEADLINE(deadline, timeout)
+	for (;;) {
+		r = connect(fd, addr, (socklen_t)len);
+		if (r == 0 || !(errno == EINPROGRESS 
+				|| errno == EINTR || errno == EISCONN)) {
+			break;	/* success or real error */
+		}
+		if (r == -1 && errno == EISCONN) {
+			/* On Solaris 2.5, after getting EINPROGRESS
+			   from a non-blocking connect request, we
+			   won't ever get success.  When we're waken
+			   up, we'll either get EISCONN, which should
+			   be taken as success, or a real failure.
+			   However, we can't map EISCONN to success
+			   inconditionally, because attempting to
+			   connect the same socket again should raise
+			   an exception.
+
+			   Mapping EISCONN to success might lead to
+			   false positives if connect fails and
+			   another thread succeeds to connect this
+			   socket before this one is waken up.  Let's
+			   just hope it doesn't happen for now.  */
+			if (inProgress) {
+				r = 0;
+			}
+			break;
+		} else if (r == -1 && errno == EINPROGRESS) {
+			inProgress = 1;
+		}
+		IGNORE_EINTR(r)
+		BREAK_IF_LATE(deadline, timeout)
+	}
+	SET_RETURN(r)
+	return (r);
+}
+
+/*
+ * Threaded socket accept.
+ */
+static int
+jthreadedAccept(int fd, struct sockaddr* addr, int* len, 
+		int timeout, int* out)
+{
+	/* absolute time at which time out is reached */
+	int r=-1, ret;	
+	ret = waitForTimeout(fd,timeout);
+
+	/* If result is 0, we had a timeout. 
+	 * If it's not, let's try to accept.
+	 */
+	if (ret != 0) {
+		r = accept(fd,addr,len);
+		SET_RETURN_OUT(r, out, r)
+		return (r);
+	}
+	else {
+		errno = ETIMEDOUT;
+		r = -1;
+	}
+	
+	SET_RETURN_OUT(r, out, r)
+	return (r);
+}
+
+/*
+ * Threaded read with timeout
+ */
+static int
+jthreadedTimedRead(int fd, void* buf, size_t len, int timeout, ssize_t *out)
+{
+	ssize_t r = -1;
+	/* absolute time at which timeout is reached */
+	int ret;
+	
+	ret = waitForTimeout(fd,timeout);
+	if (ret > 0) {
+		r = read(fd, buf, len);
+	}
+	
+	SET_RETURN_OUT(r, out, r)
+	return (r);
+}
+
+/*
+ * Threaded write with timeout
+ */
+static int
+jthreadedTimedWrite(int fd, const void* buf, size_t len, int timeout, ssize_t *out)
+{
+	ssize_t r = -1;
+	/* absolute time at which timeout is reached */
+	int ret;
+	
+	ret = waitForWritable(fd,timeout);
+	if (ret > 0) {
+		r = write(fd, buf, len);
+	}
+	
+	SET_RETURN_OUT(r, out, r)
+	return (r);
+}
+
+/*
+ * Threaded read with no time out
+ */
+static int
+jthreadedRead(int fd, void* buf, size_t len, ssize_t *out)
+{
+	ssize_t r = -1;
+
+	r = read(fd, buf, len);
+	SET_RETURN_OUT(r, out, r);
+	return (r);
+}
+
+/*
+ * Threaded write
+ */
+static int
+jthreadedWrite(int fd, const void* buf, size_t len, ssize_t *out)
+{
+	ssize_t r = 1;
+	const void* ptr;
+
+	ptr = buf;
+
+	while (len > 0 && r > 0) {
+		r = (ssize_t)write(fd, ptr, len);
+		if (r >= 0) {
+			ptr = (void *)((uintp)ptr + r);
+			len -= r;
+			r = (uintp)ptr - (uintp)buf;
+			continue;
+		}
+		if (errno == EINTR) {
+			/* ignore */
+			r = 1;
+			continue;
+		}
+		if (!(errno == EWOULDBLOCK || errno == EAGAIN)) {
+			/* real error */
+			break;
+		}
+		r = 1;
+	}
+	SET_RETURN_OUT(r, out, r)
+	return (r); 
+}
+
+/*
+ * Threaded recvfrom 
+ */
+static int 
+jthreadedRecvfrom(int fd, void* buf, size_t len, int flags, 
+	struct sockaddr* from, int* fromlen, int timeout, ssize_t *out)
+{
+	int r;
+	jlong deadline = 0;
+	int poll_timeout;
+	int blocking = jthread_is_blocking(fd);
+
+	jthread_set_blocking(fd, 0);
+	SET_DEADLINE(deadline, timeout)
+	for (;;) {
+		r = recvfrom(fd, buf, len, flags, from, fromlen);
+		if (r >= 0 || !(errno == EWOULDBLOCK || errno == EINTR 
+					|| errno == EAGAIN)) {
+			break;
+		}
+		IGNORE_EINTR(r)
+		if (timeout != NOTIMEOUT) {
+		        poll_timeout = deadline - currentTime();
+			if (poll_timeout > 0)
+			  waitForTimeout(fd, poll_timeout);
+		} else {
+			waitForTimeout(fd, NOTIMEOUT);
+		}
+		BREAK_IF_LATE(deadline, timeout)
+	}
+	jthread_set_blocking(fd, blocking);
+	SET_RETURN_OUT(r, out, r)
+	return (r);
+}
+
+/* helper function for forkexec, close fd[0..n-1] */
+static void
+close_fds(int fd[], int n)
+{
+        int i = 0;
+        while (i < n) {
+                close(fd[i++]);
+	}
+}
+
+static int 
+jthreadedForkExec(char **argv, char **arge,
+	int ioes[4], int *outpid, const char *dir)
+{
+/* these defines are indices in ioes */
+#define IN_IN		0
+#define IN_OUT		1
+#define OUT_IN		2
+#define OUT_OUT		3
+#define ERR_IN		4
+#define ERR_OUT		5
+#define SYNC_IN		6
+#define SYNC_OUT	7
+
+	int fds[8];
+	int nfd;		/* number of fds in `fds' that are valid */
+	sigset_t nsig, osig;
+	char b[1];
+	int pid, i, err;
+
+	/* 
+	 * we need execve() and fork() for this to work.  Don't bother if
+	 * we don't have them.
+	 */
+#if !defined(HAVE_EXECVE) && !defined(HAVE_EXECVP)
+	unimp("neither execve() nor execvp() provided");
+#endif
+#if !defined(HAVE_FORK)
+	unimp("fork() not provided");
+#endif
+
+	/* Create the pipes to communicate with the child */
+	/* Make sure fds get closed if we can't create all pipes */
+	for (nfd = 0; nfd < 8; nfd += 2) {
+		int e;
+		err = pipe(fds + nfd);
+		e = errno;
+		if (err == -1) {
+			close_fds(fds, nfd);
+			return (e);
+		}
+	}
+
+	/* 
+	 * We must avoid that the child dies because of SIGVTALRM or
+	 * other signals.  We disable interrupts before forking and then
+	 * reenable signals in the child after we cleaned up.
+	 */
+	sigfillset(&nsig);
+	sigprocmask(SIG_BLOCK, &nsig, &osig);
+
+	pid = fork();
+
+	switch (pid) {
+	case 0:
+		/* Child */
+		/* set all signals back to their default state */
+		for (i = 0; i < NSIG; i++) {
+			clearSignal(i);
+		}
+
+		/* now reenable interrupts */
+		sigprocmask(SIG_UNBLOCK, &nsig, NULL);
+
+		/* set stdin, stdout, and stderr up from the pipes */
+		dup2(fds[IN_IN], 0);
+		dup2(fds[OUT_OUT], 1);
+		dup2(fds[ERR_OUT], 2);
+
+		/* What is sync about anyhow?  Well my current guess is that
+		 * the parent writes a single byte to it when it's ready to
+		 * proceed.  So here I wait until I get it before doing
+		 * anything.
+		 */
+		/* note that this is a blocking read */
+		read(fds[SYNC_IN], b, sizeof(b));
+
+		/* now close all pipe fds */
+		close_fds(fds, 8);
+
+		/* change working directory */
+#if defined(HAVE_CHDIR)
+		(void)chdir(dir);
+#endif
+
+		/*
+		 * If no environment was given and we have execvp, we use it.
+		 * If an environment was given, we use execve.
+		 * This is roughly was the linux jdk seems to do.
+		 */
+
+		/* execute program */
+#if defined(HAVE_EXECVP)
+		if (arge == NULL)
+			execvp(argv[0], argv);
+		else
+#endif
+			execve(argv[0], argv, arge);
+		break;
+
+	case -1:
+		/* Error */
+		err = errno;
+		/* Close all pipe fds */
+		close_fds(fds, 8);
+		sigprocmask(SIG_UNBLOCK, &osig, NULL);
+		return (err);
+
+	default:
+		/* Parent */
+		/* close the fds we won't need */
+		close(fds[IN_IN]);
+		close(fds[OUT_OUT]);
+		close(fds[ERR_OUT]);
+		close(fds[SYNC_IN]);
+
+		/* copy and fix up the fds we do need */
+		ioes[0] = fds[IN_OUT];
+		ioes[1] = fds[OUT_IN];
+		ioes[2] = fds[ERR_IN];
+		ioes[3] = fds[SYNC_OUT];
+
+		sigprocmask(SIG_UNBLOCK, &osig, NULL);
+		*outpid = pid;
+		return (0);
+	}
+
+	exit(-1);
+	/* NEVER REACHED */	
+}
+
+/* 
+ * Wait for a child process.
+ */
+static int
+jthreadedWaitpid(int wpid, int* status, int options, int *outpid)
+{
+#if defined(HAVE_WAITPID)
+	int npid;
+	sigset_t sigdata;
+
+	KaffePThread_setBlockingCall(&sigdata);
+	npid = waitpid(wpid, status, options);
+	KaffePThread_clearBlockingCall(&sigdata);
+	if (npid > 0) {
+		*outpid = npid;
+		return (0);
+	}
+	else {
+		return (-1);
+	}
+#else
+	return (-1);
+#endif
+}
+
+static int
+jthreadedMmap(void **memory, size_t *size, int mode, int fd, off_t *offset)
+{
+#if defined(HAVE_MMAP)
+	size_t pages_sz;
+	off_t pages_offset;
+	int sysmode, sysflags;
+	int rc = 0;
+
+	pages_sz = (*size)/getpagesize();
+	*size = (pages_sz+1)*getpagesize();
+  
+	pages_offset = (*offset)/getpagesize();
+	*offset = pages_offset*getpagesize();
+
+	switch (mode) {
+		case KAFFE_MMAP_READ:
+			sysflags = MAP_SHARED;
+			sysmode = PROT_READ;
+			break;
+		case KAFFE_MMAP_WRITE:
+			sysflags = MAP_SHARED;
+			sysmode = PROT_WRITE | PROT_READ;
+			break;
+		case KAFFE_MMAP_PRIVATE:
+			sysflags = MAP_PRIVATE;
+			sysmode = PROT_WRITE | PROT_READ;
+			break;
+		default:
+			return -EINVAL;
+	}
+
+	*memory = mmap(*memory, *size, sysmode, sysflags, fd, *offset);
+
+	return (rc);
+#else
+	return (ENOTSUP);
+#endif
+}
+
+
+static int
+jthreadedMunmap(void *memory, size_t size)
+{
+#if defined(HAVE_MMAP)
+	int rc = 0;
+	
+	if (munmap(memory, size) < 0) {
+		rc = errno;
+	}
+	return (rc);
+#else
+	return (ENOTSUP);
+#endif
+}
+
+static int
+jthreadedMsync(void *memory, size_t size)
+{
+#if defined(HAVE_MMAP)
+        int rc = 0;
+
+        memory = (void *)(((size_t)memory/getpagesize()) * getpagesize());
+        size += getpagesize();
+        /* TODO: Try not to freeze the entire VM. */
+        if (msync(memory, size, MS_SYNC | MS_INVALIDATE) < 0) {
+            rc = errno;
+        }
+
+        return rc;
+#else
+        return (ENOTSUP);
+#endif
+}
+
+static int
+jthreadedPipeCreate(int *read_fd, int *write_fd)
+{
+	int pairs[2];
+
+	assert(read_fd != NULL);
+	assert(write_fd != NULL);
+
+	if (pipe(pairs) < 0)
+		return errno;
+
+	*read_fd = pairs[0];
+	*write_fd = pairs[1];
+
+	return 0;
+}
+
+/*
+ * The syscall interface as provided by the internal jthread system.
+ */
+SystemCallInterface Kaffe_SystemCallInterface = {
+        jthreadedOpen,
+        jthreadedRead,	
+        jthreadedWrite, 
+        jthreadedLSeek,
+        jthreadedClose,
+        jthreadedFStat,
+        jthreadedStat,
+        jthreadedFTruncate,
+        jthreadedFSync,
+        jthreadedMkdir,
+        jthreadedRmdir,
+        jthreadedRename,
+        jthreadedRemove,
+        jthreadedSocket,
+        jthreadedConnect,
+        jthreadedBind,
+        jthreadedListen,
+        jthreadedAccept, 
+        jthreadedTimedRead,	
+        jthreadedRecvfrom,
+        jthreadedWrite, 
+        jthreadedSendto,	
+        jthreadedSetSockOpt,	
+        jthreadedGetSockOpt,
+        jthreadedGetSockName, 
+        jthreadedGetPeerName, 
+        jthreadedClose,
+        jthreadedGetHostByName,
+        jthreadedGetHostByAddr,
+        jthreadedSelect,	
+        jthreadedForkExec,
+        jthreadedWaitpid,
+        jthreadedKill,
+        jthreadedMmap,
+        jthreadedMunmap,
+	jthreadedMsync,
+	jthreadedPipeCreate,
+	jthreadedTimedRead,
+	jthreadedTimedWrite
+};



More information about the kaffe mailing list