The unified diff between revisions [a7f61676..] and [43bb367e..] is displayed below. It can also be downloaded as a raw diff.

This diff has been restricted to the following files: 'src/lsi/vm.c'

#
# old_revision [a7f61676c8d04ecf082be8ae39a40b4e7bba3462]
# new_revision [43bb367e69d2a944206fd7f641ce73111e4bb780]
#
# patch "src/lsi/vm.c"
#  from [2f4df836fac21746563e434768e4f832c1ea3e15]
#    to [f74e79e92252eafbcbc81d3ee4ca5e2e3c79f4a9]
#
============================================================
--- src/lsi/vm.c	2f4df836fac21746563e434768e4f832c1ea3e15
+++ src/lsi/vm.c	f74e79e92252eafbcbc81d3ee4ca5e2e3c79f4a9
@@ -11,6 +11,7 @@
 #include <fcntl.h>
 #include <errno.h>
 #include <math.h>
+#include <stdarg.h>
 
 #include "vm.h"
 #include "code.h"
@@ -21,6 +22,7 @@
 #include "beatdetect.h"
 #include "map3d.h"
 #include "mouse.h"
+#include "cmdsocket.h"
 
 #define DEBUG 0
 
@@ -41,6 +43,9 @@ struct vm_thread {
 
 #define ARRAYBLOCKSIZE	512
 
+#define SLEEPTIME_SEC	60
+#define SLEEPTIME_NSEC	0
+
 struct pollfd vm_pollfd[VM_MAXPOLLFD];
 int vm_pollfdqueue[VM_MAXPOLLFD];
 
@@ -55,6 +60,7 @@ size_t vm_codesize = 0;
 
 instr *vm_codearea = NULL;
 size_t vm_codesize = 0;
+int vm_threads = 0;
 
 struct hashentry *fnhash[HASHSIZE];
 struct hashentry *globhash[HASHSIZE];
@@ -418,6 +424,46 @@ int vm_intfn_mouse_read(void)
 	return 0;
 }
 
+int vm_intfn_cmdsocket_listen(void)
+{
+	stack_poke(vm_current, 0,
+	    cmdsocket_listen(stack_get(vm_current, 1)));
+	return 1;
+}
+
+int vm_intfn_cmdsocket_prefix(void)
+{
+	char buf[VM_STRING_MAX];
+	int len = stack_get(vm_current, 1);
+
+	strncpy(buf, stack_getstr(vm_current, len, 1), len);
+	buf[len] = '\0';
+
+	cmdsocket_prefix(buf);
+
+	return 1;
+}
+
+int vm_intfn_cmdsocket_accept(void)
+{
+	if (!cmdsocket_accept()) {
+	    vm_queue(vm_current, VM_CMDLISTENQ);
+	    vm_current = NULL;
+	    return 0;
+	}
+	return 1;
+}
+
+int vm_intfn_cmdsocket_read(void)
+{
+	if (!cmdsocket_read()) {
+		vm_queue(vm_current, VM_CMDREADQ);
+		vm_current = NULL;
+		return 0;
+	}
+	return 1;
+}
+
 int vm_intfn_beatdetect_read(void)
 {
 	if (!beatdetect_read()) {
@@ -570,6 +616,7 @@ void vm_init(void)
 	vm_npollfds = 0;
 	vm_caughtsignal = 0;
 	signal(SIGIO, vm_sighandler);
+	signal(SIGPIPE, SIG_IGN);
 }
 
 void vm_load_file(char *filename)
@@ -673,10 +720,11 @@ void vm_queue(struct vm_thread *thread, 
 	vm_queues[queue] = thread;
 }
 
-int vm_spawn(char *fn)
+int vm_spawn_args(char *fn, int n, ...)
 {
 	struct vm_thread *newt;
 	struct hashentry *ptr;
+	va_list ap;
 
 	ptr = hash_lookup(fnhash, fn, 0);
 	if (ptr == NULL) {
@@ -705,6 +753,12 @@ int vm_spawn(char *fn)
 	/* Push return address here, to point to some special thread exit
 	   routine */
 
+	/* Push optional arguments */
+	va_start(ap, n);
+	while (n--)
+	    stack_push(newt, va_arg(ap, int));
+	va_end(ap);
+
 	stack_push(newt, 0); 	/* Return value */
 	stack_push(newt, 0);	/* Return address */
 
@@ -712,15 +766,26 @@ int vm_spawn(char *fn)
 	newt->prev = NULL;
 	newt->queue = VM_NOQUEUE;
 	vm_queue(newt, VM_RUNQ);
+	vm_threads++;
 
 	return 1;
 }
 
+int vm_spawn(char *fn)
+{
+	return vm_spawn_args(fn, 0);
+}
+
 void vm_destroy(struct vm_thread *thread)
 {
 	vm_unqueue(thread);
 	free(thread->stackbase);
 	free(thread);
+	vm_threads--;
+	if (vm_threads == 0) {
+		printf("No threads left\n");
+		exit(0);
+	}
 }
 
 int vm_runnable(struct vm_thread *thread)
@@ -757,18 +822,19 @@ void vm_sched(void)
 		struct timespec ts;
 		int rv;
 
-		if (vm_queues[VM_TIMEQ] == NULL) {
-			printf("No runnable thread, and no waiting thread\n");
-			exit(0);
-		}
 //		printf("No runnable thread - sleeping\n");
-		gettimeofday(&tv, NULL);
-		timersub(&vm_queues[VM_TIMEQ]->time, &tv, &tv);
-		if ((tv.tv_sec < 0) || (tv.tv_usec < 0)) {
-			tv.tv_sec = 0;
-			tv.tv_usec = 0;
+		if (vm_queues[VM_TIMEQ]) {
+		    gettimeofday(&tv, NULL);
+		    timersub(&vm_queues[VM_TIMEQ]->time, &tv, &tv);
+		    if ((tv.tv_sec < 0) || (tv.tv_usec < 0)) {
+			    tv.tv_sec = 0;
+			    tv.tv_usec = 0;
+		    }
+		    TIMEVAL_TO_TIMESPEC(&tv, &ts);
+		} else {
+		    ts.tv_sec = SLEEPTIME_SEC;
+		    ts.tv_nsec = SLEEPTIME_NSEC;
 		}
-		TIMEVAL_TO_TIMESPEC(&tv, &ts);
 //		nanosleep(&ts, NULL);
 		rv = pollts(vm_pollfd, vm_npollfds, &ts, NULL);
 		if ((rv == -1) && (errno != EINTR))
@@ -791,6 +857,20 @@ void vm_register_signal_fd(int fd, int q
 	rv = fcntl(fd, F_SETFL, O_NONBLOCK | O_ASYNC);
 }
 
+void vm_unregister_signal_fd(int fd)
+{
+	int i;
+
+	for (i = 0; i < vm_npollfds; i++) {
+	    if (fd == vm_pollfd[i].fd) {
+		memmove(&vm_pollfd[i], &vm_pollfd[i+1],
+		    sizeof(struct pollfd) * (vm_npollfds-i-1));
+		vm_npollfds--;
+		return;
+	    }
+	}
+}
+
 void stack_push(struct vm_thread *thread, stkentry e)
 {
 	thread->sp++;