# # patch "src/colinux/os/linux/test/pipe_server.c" # from [81cca44acd4de7c373ce17934b555b5dde647213] # to [57f3e2d790dd24e79baf19bb9281b62a87bede53] # # patch "src/colinux/os/linux/user/conet-daemon/main.c" # from [0477921aa4636ce57f6070f996ba94641f5fe8c2] # to [6c4b329034f88265036cb158b497bc11b4d205d3] # # patch "src/colinux/os/linux/user/conet-slirp-daemon/main.c" # from [aa781edd0e4f7adf59aaf032f0ad046a468b547a] # to [15cd5346f800ef85574aa926619910d7e4e743f1] # # patch "src/colinux/os/linux/user/coserial-daemon/main.c" # from [2b1358c8ceb0eb14507b903562866177c141f5b3] # to [6098fe1efeb7aba16c5f4f2fcb53c13dd2d04df5] # # patch "src/colinux/os/linux/user/daemon.c" # from [13e261c2d80339321506fe399f94e0a595f08962] # to [8abd4e9026e2e48329e11c4527774877b5efa8be] # # patch "src/colinux/os/user/daemon.h" # from [7c214fc518203cf407b08ea044109762fca1976f] # to [75356d5b4d6624cb38211ceebc169461bea24c45] # # patch "src/colinux/os/winnt/user/conet-bridged-daemon/main.c" # from [7efdbdb1aff3c5e0be4b448d4f985506cff8e266] # to [06bf21c287928613211e4caa2bd4e26796172a38] # # patch "src/colinux/os/winnt/user/conet-daemon/main.c" # from [328eff1a1d2c4176a77d159a812686fa3cffe3ca] # to [8e61526f9195545ca1608ffed3025b65cf24307d] # # patch "src/colinux/os/winnt/user/conet-slirp-daemon/main.c" # from [800c483379ec2b4412fef6a4ae14a294654addb8] # to [dd2766d0c82a95ac75cc9c2e8603d26eda18909f] # # patch "src/colinux/os/winnt/user/coserial-daemon/main.c" # from [fb24c6900531e7989fa8d3bcc778166a9b4d0026] # to [cd410fc0cbeacc2b0ee743fadeb667cdc3b07f93] # # patch "src/colinux/os/winnt/user/daemon.c" # from [dacfbc4c182ca8ac6d8d51ae4af896317d7b84d0] # to [8b9183b27cb1befbc80196e74da65de3204665e7] # # patch "src/colinux/user/console-base/console.cpp" # from [9b490b165d0b133461f69078bdb72d9d8d44b8dc] # to [3d44c88a6dc154849ad1d801e92784e2fed013c9] # # patch "src/colinux/user/console/console.cpp" # from [a897a03e0c45c0c3935f3d66fa2e51aff5ebc1c5] # to [9a434cb18410949501209340e99dd2fe021e855f] # --- src/colinux/os/linux/test/pipe_server.c +++ src/colinux/os/linux/test/pipe_server.c @@ -17,10 +17,10 @@ } message = {{0,}}, *in_message; int i = 0; - rc = co_os_open_daemon_pipe(0, 41234, &handle); + rc = co_os_daemon_pipe_open(0, 41234, &handle); if (!CO_OK(rc)) { - co_debug("co_os_open_daemon_pipe: %x\n", rc); + co_debug("co_os_daemon_pipe_open: %x\n", rc); return rc; } @@ -32,10 +32,10 @@ message.message.size = 0x2000; message.message.from = 0x10; snprintf(message.payload, sizeof(message.payload), "asd"); - co_os_daemon_send_message(handle, &message.message); + co_os_daemon_message_send(handle, &message.message); printf("receiving %d\n", i); - rc = co_os_daemon_get_message(handle, &in_message, 10); + rc = co_os_daemon_message_receive(handle, &in_message, 10); if (!CO_OK(rc)) { printf("error: %08x\n", rc); @@ -48,7 +48,7 @@ } - co_os_daemon_close(handle); + co_os_daemon_pipe_close(handle); return 0; } --- src/colinux/os/linux/user/conet-daemon/main.c +++ src/colinux/os/linux/user/conet-daemon/main.c @@ -114,7 +114,7 @@ message.msg_linux.unit = 0; message.msg_linux.size = read_size; - rc = co_os_daemon_send_message(daemon_handle, &message.message); + rc = co_os_daemon_message_send(daemon_handle, &message.message); } if (revents & (POLLERR | POLLHUP)) { @@ -208,14 +208,14 @@ co_terminal_print("TAP interface %s created\n", tap_name); - rc = co_os_open_daemon_pipe(0, CO_MODULE_CONET0, &daemon_handle_); + rc = co_os_daemon_pipe_open(0, CO_MODULE_CONET0, &daemon_handle_); if (!CO_OK(rc)) { co_terminal_print("Error opening a pipe to the daemon\n"); goto out_close; } wait_loop(daemon_handle_, tap_fd); - co_os_daemon_close(daemon_handle_); + co_os_daemon_pipe_close(daemon_handle_); out_close: close(tap_fd); --- src/colinux/os/linux/user/conet-slirp-daemon/main.c +++ src/colinux/os/linux/user/conet-slirp-daemon/main.c @@ -61,7 +61,7 @@ memcpy(message.data, pkt, pkt_len); - co_os_daemon_send_message(daemon_handle, &message.message); + co_os_daemon_message_send(daemon_handle, &message.message); } static co_rc_t wait_loop(void) @@ -134,7 +134,7 @@ { co_rc_t rc = CO_RC(ERROR); - rc = co_os_open_daemon_pipe(instance, CO_MODULE_CONET0 + unit, &daemon_handle); + rc = co_os_daemon_pipe_open(instance, CO_MODULE_CONET0 + unit, &daemon_handle); if (!CO_OK(rc)) { co_terminal_print("conet_slirp: error opening a pipe to the daemon\n"); goto out; @@ -142,7 +142,7 @@ rc = wait_loop(); - co_os_daemon_close(daemon_handle); + co_os_daemon_pipe_close(daemon_handle); out: return rc; } --- src/colinux/os/linux/user/coserial-daemon/main.c +++ src/colinux/os/linux/user/coserial-daemon/main.c @@ -94,7 +94,7 @@ message.msg_linux.unit = unit; message.msg_linux.size = read_size; - rc = co_os_daemon_send_message(daemon_handle, &message.message); + rc = co_os_daemon_message_send(daemon_handle, &message.message); } if (revents & (POLLERR | POLLHUP)) { @@ -159,7 +159,7 @@ co_rc_t rc = CO_RC(ERROR); struct termios term; - rc = co_os_open_daemon_pipe(instance, CO_MODULE_SERIAL0 + unit, &daemon_handle_); + rc = co_os_daemon_pipe_open(instance, CO_MODULE_SERIAL0 + unit, &daemon_handle_); if (!CO_OK(rc)) { co_terminal_print("coserial: error opening a pipe to the daemon\n"); goto out; @@ -175,7 +175,7 @@ rc = wait_loop(daemon_handle_, unit, 0, 1); - co_os_daemon_close(daemon_handle_); + co_os_daemon_pipe_close(daemon_handle_); out: return rc; } --- src/colinux/os/linux/user/daemon.c +++ src/colinux/os/linux/user/daemon.c @@ -23,7 +23,7 @@ #include "pipe.h" co_rc_t -co_os_open_daemon_pipe(co_id_t linux_id, co_module_t module_id, +co_os_daemon_pipe_open(co_id_t linux_id, co_module_t module_id, co_daemon_handle_t *handle_out) { int sock, ret; @@ -92,7 +92,7 @@ } co_rc_t -co_os_daemon_get_message(co_daemon_handle_t handle, +co_os_daemon_message_get(co_daemon_handle_t handle, co_message_t **message_out, unsigned long timeout) { @@ -119,13 +119,13 @@ } co_rc_t -co_os_daemon_send_message(co_daemon_handle_t handle, co_message_t *message) +co_os_daemon_message_receive(co_daemon_handle_t handle, co_message_t *message) { return co_os_frame_send(handle->sock, (char *)message, message->size + sizeof(*message)); } void -co_os_daemon_close(co_daemon_handle_t handle) +co_os_daemon_pipe_close(co_daemon_handle_t handle) { close(handle->sock); co_os_free(handle); --- src/colinux/os/user/daemon.h +++ src/colinux/os/user/daemon.h @@ -16,12 +16,12 @@ struct co_daemon_handle; typedef struct co_daemon_handle *co_daemon_handle_t; -extern co_rc_t co_os_open_daemon_pipe(co_id_t linux_id, co_module_t module_id, co_daemon_handle_t *handle_out); -extern co_rc_t co_os_daemon_get_message(co_daemon_handle_t handle, co_message_t **message, unsigned long timeout); -extern co_rc_t co_os_daemon_send_message(co_daemon_handle_t handle, co_message_t *message); -extern void co_os_daemon_close(co_daemon_handle_t handle); +extern co_rc_t co_os_daemon_pipe_open(co_id_t linux_id, co_module_t module_id, co_daemon_handle_t *handle_out); +extern co_rc_t co_os_daemon_pipe_close(co_daemon_handle_t handle); +extern co_rc_t co_os_daemon_message_receive(co_daemon_handle_t handle, co_message_t **message, unsigned long timeout); +extern co_rc_t co_os_daemon_message_send(co_daemon_handle_t handle, co_message_t *message); +extern co_rc_t co_os_daemon_message_deallocate(co_daemon_handle_t handle, co_message_t *message); extern void co_daemon_debug(char *str); extern void co_daemon_print_header(void); -extern void co_os_daemon_deallocate_message(co_message_t*); #endif --- src/colinux/os/winnt/user/conet-bridged-daemon/main.c +++ src/colinux/os/winnt/user/conet-bridged-daemon/main.c @@ -661,7 +661,7 @@ goto out; } - rc = co_os_open_daemon_pipe(daemon_parameters->instance, + rc = co_os_daemon_pipe_open(daemon_parameters->instance, CO_MODULE_CONET0 + daemon_parameters->index, &daemon_handle_); if (!CO_OK(rc)) { co_terminal_print("Error opening a pipe to the daemon\n"); @@ -676,7 +676,7 @@ daemon_handle = daemon_handle_->handle; exit_code = wait_loop(daemon_handle); - co_os_daemon_close(daemon_handle_); + co_os_daemon_pipe_close(daemon_handle_); out: ExitProcess(exit_code); --- src/colinux/os/winnt/user/conet-daemon/main.c +++ src/colinux/os/winnt/user/conet-daemon/main.c @@ -423,7 +423,7 @@ } - rc = co_os_open_daemon_pipe(daemon_parameters->instance, + rc = co_os_daemon_pipe_open(daemon_parameters->instance, CO_MODULE_CONET0 + daemon_parameters->index, &daemon_handle_); if (!CO_OK(rc)) { co_terminal_print("Error opening a pipe to the daemon\n"); @@ -432,7 +432,7 @@ daemon_handle = daemon_handle_->handle; exit_code = wait_loop(daemon_handle, tap_handle); - co_os_daemon_close(daemon_handle_); + co_os_daemon_pipe_close(daemon_handle_); out_close: CloseHandle(tap_handle); --- src/colinux/os/winnt/user/conet-slirp-daemon/main.c +++ src/colinux/os/winnt/user/conet-slirp-daemon/main.c @@ -388,7 +388,7 @@ co_terminal_print("Slirp initialized\n"); daemon_parameters = &start_parameters; - rc = co_os_open_daemon_pipe(daemon_parameters->instance, + rc = co_os_daemon_pipe_open(daemon_parameters->instance, CO_MODULE_CONET0 + daemon_parameters->index, &daemon_handle_); if (!CO_OK(rc)) { co_terminal_print("Error opening a pipe to the daemon\n"); @@ -409,7 +409,7 @@ CloseHandle(slirp_mutex); out_close: - co_os_daemon_close(daemon_handle_); + co_os_daemon_pipe_close(daemon_handle_); out: co_debug_end(); --- src/colinux/os/winnt/user/coserial-daemon/main.c +++ src/colinux/os/winnt/user/coserial-daemon/main.c @@ -327,7 +327,7 @@ daemon_parameters = &start_parameters; - rc = co_os_open_daemon_pipe(daemon_parameters->instance, + rc = co_os_daemon_pipe_open(daemon_parameters->instance, CO_MODULE_SERIAL0 + daemon_parameters->index, &daemon_handle_); if (!CO_OK(rc)) { co_terminal_print("Error opening a pipe to the daemon\n"); @@ -336,7 +336,7 @@ daemon_handle = daemon_handle_->handle; exit_code = wait_loop(daemon_handle); - co_os_daemon_close(daemon_handle_); + co_os_daemon_pipe_close(daemon_handle_); out: co_debug_end(); --- src/colinux/os/winnt/user/daemon.c +++ src/colinux/os/winnt/user/daemon.c @@ -7,15 +7,6 @@ * the root directory. */ -/* - * Ballard, Jonathan H. - * 20040222 : Designed and implemented co_os_daemon_thread() - * : with message queue, wait state, and error - * : recovery. - * 20050117 : Updated message queue to use co_message_packet_t, - * : allocate_message() and co_os_daemon_deallocate_message() - */ - #include #include @@ -24,207 +15,67 @@ #include #include -static DWORD WINAPI co_os_daemon_thread(LPVOID data); +/* + * Queue iteration threshold for packet retention and deallocation + */ + +#define PACKET_RETENTION 3 -typedef struct co_message_packet { - struct co_message_packet *next; +typedef struct _packet { + struct _packet *next; unsigned size; - unsigned free; - co_message_t data[0]; -} co_message_packet_t; + unsigned free; // ==0 allocated, !=0 iteration count + co_message_t message[0]; +} packet_t; -co_rc_t -co_os_open_daemon_pipe(co_id_t linux_id, co_module_t module_id, - co_daemon_handle_t * handle_out) +static packet_t * +packet_allocate(co_daemon_handle_t daemon, size_t size) { - HANDLE handle = INVALID_HANDLE_VALUE; - long written = 0; - char pathname[0x100]; - co_daemon_handle_t daemon_handle = 0; - co_module_name_t module_name; + packet_t *packet = daemon->packets; + packet_t **shadow = (packet_t**)&daemon->packets; - snprintf(pathname, sizeof (pathname), "\\\\.\\pipe\\coLinux%d", - (int) linux_id); - - co_module_repr(module_id, &module_name); - - co_debug("connecting to instance %d as %s\n", linux_id, module_name); - - if (!WaitNamedPipe(pathname, NMPWAIT_USE_DEFAULT_WAIT)) { - co_debug("connection timed out (%x)\n", GetLastError()); - goto co_os_open_daemon_pipe_error; - } - - co_debug("connection established\n"); - - handle = CreateFile(pathname, - GENERIC_READ | GENERIC_WRITE, - 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); - - if (handle == INVALID_HANDLE_VALUE) - goto co_os_open_daemon_pipe_error; - - /* Identify ourselves to the daemon */ - if (!WriteFile(handle, &module_id, sizeof (module_id), &written, NULL)) { - co_debug("attachment failed\n"); - goto co_os_open_daemon_pipe_error; - } - - if (!(daemon_handle = co_os_malloc(sizeof (*daemon_handle)))) - goto co_os_open_daemon_pipe_error; - - daemon_handle->handle = handle; - daemon_handle->loop = 1; - daemon_handle->rc = CO_RC(OK); - daemon_handle->message = 0; - daemon_handle->shifted = CreateEvent(0, FALSE, FALSE, 0); - daemon_handle->readable = CreateEvent(0, TRUE, TRUE, 0); - if (!(daemon_handle->shifted && daemon_handle->readable)) - goto co_os_open_daemon_pipe_error; - - co_debug_lvl(pipe,10,"user daemon thread starting"); - daemon_handle->thread = - CreateThread(0, 0, co_os_daemon_thread, daemon_handle, 0, 0); - - if (daemon_handle->thread) { - *handle_out = daemon_handle; - return CO_RC(OK); - } - - co_debug("co_os_daemon_thread() did not start\n"); - - co_os_open_daemon_pipe_error: - - if (daemon_handle) { - if (daemon_handle->readable) - CloseHandle(daemon_handle->readable); - if (daemon_handle->shifted) - CloseHandle(daemon_handle->shifted); - if (daemon_handle->thread) - CloseHandle(daemon_handle->thread); - co_os_free(daemon_handle); - } - - if (handle != INVALID_HANDLE_VALUE) - CloseHandle(handle); - - return CO_RC(ERROR); -} - -static co_message_packet_t * -allocate_message(co_daemon_handle_t D, size_t size) -{ - co_message_packet_t *m = D->packets; - co_message_packet_t **p = (co_message_packet_t**)&D->packets; - - while(m) { - if(m->free) { - if(m->size >= size && size >= (m->size >> 1)) { - m->free = 0; - *p = m->next; - m->next = 0; - return m; + while(packet) { + if(packet->free) { + if(packet->size >= size && size >= (packet->size >> 1)) { + packet->free = 0; + *shadow = packet->next; + packet->next = 0; + return packet; } - if(++m->free <= 3) { // retention threshold - p = &m->next; - m = m->next; + if(++packet->free <= PACKET_RETENTION) { + shadow = &packet->next; + packet = packet->next; continue; } - *p = m->next; - HeapFree(D->heap, HEAP_NO_SERIALIZE, m); -// co_os_free(m); - m = *p; + *shadow = packet->next; + HeapFree(daemon->heap, HEAP_NO_SERIALIZE, packet); + packet = *shadow; continue; } - p = &m->next; - m = m->next; + shadow = &packet->next; + packet = packet->next; } - m = HeapAlloc(D->heap, HEAP_NO_SERIALIZE, sizeof(struct co_message_packet)+size); -// m = co_os_malloc(sizeof(struct co_message_packet)+size); - if(!m) + if(!(packet = HeapAlloc(daemon->heap, HEAP_NO_SERIALIZE, sizeof(packet_t)+size))) return NULL; - m->next = 0; - m->free = 0; - m->size = size; - return m; + packet->next = 0; + packet->free = 0; + packet->size = size; + return packet; } -void -co_os_daemon_deallocate_message(co_message_t *m) +static DWORD WINAPI io_thread(LPVOID param) { - co_message_packet_t *p; - - p = (co_message_packet_t*)((unsigned)m - sizeof(struct co_message_packet)); - p->free = 1; -} - -co_rc_t -co_os_daemon_get_message(co_daemon_handle_t handle, - co_message_t ** message_out, unsigned long timeout) -{ - DWORD r; - co_rc_t rc = handle->rc; - - *message_out = NULL; - - if (handle->message) { - *message_out = handle->message; - handle->message = 0; - return CO_RC(OK); - } - - if (!CO_OK(rc)) - return rc; - - SetEvent(handle->shifted); - - r = MsgWaitForMultipleObjects(1, &handle->readable, FALSE, timeout, - QS_ALLEVENTS); - if (r == WAIT_TIMEOUT || r == WAIT_OBJECT_0 + 1) { - return CO_RC(TIMEOUT); - } - - if (handle->message) { - *message_out = handle->message; - handle->message = 0; - } - SetEvent(handle->shifted); - - return CO_RC(OK); -} - -co_rc_t -co_os_daemon_send_message(co_daemon_handle_t handle, co_message_t * message) -{ - unsigned long bytes_written; - unsigned long bytes_to_write = sizeof (*message) + message->size; - BOOL ret; - - ret = WriteFile(handle->handle, (char *) message, - bytes_to_write, &bytes_written, NULL); - - if (ret != TRUE) - return CO_RC(ERROR); - - if (bytes_written != bytes_to_write) - return CO_RC(ERROR); - - return CO_RC(OK); -} - -static DWORD WINAPI -co_os_daemon_thread(LPVOID D) -{ - co_daemon_handle_t d = D; - HANDLE h = d->handle; - HANDLE w[2]; + co_daemon_handle_t daemon = param; + HANDLE pipe = daemon->handle; OVERLAPPED overlapped; - DWORD r; - co_message_packet_t *data = 0; - co_message_packet_t *p = 0; bool_t async = PFALSE; + packet_t *packet = 0; + HANDLE events[2]; + packet_t *p = 0; co_rc_t rc; + DWORD size; + DWORD code; # define NT_ERROR(_1) { \ co_debug_lvl(pipe,1,"co_os_daemon_thread() error [ %x , %s ]\n", \ @@ -233,9 +84,9 @@ goto co_os_daemon_thread_error; \ } - d->qIn = d->qOut = d->packets = 0; + daemon->qIn = daemon->qOut = daemon->packets = 0; co_debug_lvl(pipe,10,"user daemon thread started"); - d->heap = HeapCreate(HEAP_NO_SERIALIZE, 0x10000, 0x100000); + daemon->heap = HeapCreate(HEAP_NO_SERIALIZE, 0x10000, 0x100000); memset(&overlapped, 0, sizeof (overlapped)); overlapped.hEvent = CreateEvent(0, TRUE, FALSE, 0); @@ -243,76 +94,77 @@ if (!overlapped.hEvent) NT_ERROR("CE001"); - w[0] = overlapped.hEvent; - w[1] = d->shifted; + events[0] = overlapped.hEvent; + events[1] = daemon->shifted; co_os_daemon_thread_loop: - if (WaitForSingleObject(w[1], INFINITE) == WAIT_FAILED) + if (WaitForSingleObject(events[1], INFINITE) == WAIT_FAILED) NT_ERROR("W0001"); - while (d->loop) { - if ((!d->message) && d->qOut) { - p = d->qOut; - if(! (d->qOut = p->next) ) - d->qIn = 0; - p->next = d->packets; - d->packets = p; - d->message = p->data; - if (!SetEvent(d->readable)) + while (daemon->loop) { + if ((!daemon->message) && daemon->qOut) { + p = daemon->qOut; + if(! (daemon->qOut = p->next) ) + daemon->qIn = 0; + p->next = daemon->packets; + daemon->packets = p; + daemon->message = p->message; + // p = 0; + if (!SetEvent(daemon->readable)) NT_ERROR("SE0001"); } if (async) { - r = WaitForMultipleObjects(2, w, FALSE, INFINITE); - if(r == WAIT_FAILED) + code = WaitForMultipleObjects(2, events, FALSE, INFINITE); + if(code == WAIT_FAILED) NT_ERROR("W0002"); - if (!d->message) - if (!ResetEvent(d->readable)) + if (!daemon->message) + if (!ResetEvent(daemon->readable)) NT_ERROR("RE0001"); - if (r != WAIT_OBJECT_0) + if (code != WAIT_OBJECT_0) continue; - if (!GetOverlappedResult(h, &overlapped, &r, FALSE)) { - r = GetLastError(); - if (r == ERROR_IO_INCOMPLETE) + if (!GetOverlappedResult(pipe, &overlapped, &size, FALSE)) { + code = GetLastError(); + if (code == ERROR_IO_INCOMPLETE) continue; - if (r == ERROR_IO_PENDING) + if (code == ERROR_IO_PENDING) continue; - if (r == ERROR_BROKEN_PIPE) + if (code == ERROR_BROKEN_PIPE) goto co_os_daemon_thread_broken_pipe; NT_ERROR("GOR01"); } - if(!r) { - data->free = 1; - data->next = d->packets; - d->packets = data; + if(!size) { + packet->free = 1; + packet->next = daemon->packets; + daemon->packets = packet; } else { - if(r < sizeof(co_message_t)) + if(size < sizeof(co_message_t)) NT_ERROR("DS0001"); - if(r != data->data->size + sizeof(co_message_t)) + if(size != packet->message->size + sizeof(co_message_t)) NT_ERROR("DS0002"); - if(!d->qOut) { - d->qOut = d->qIn = data; + if(!daemon->qOut) { + daemon->qOut = daemon->qIn = packet; } else { - ((co_message_packet_t*)d->qIn)->next = data; - d->qIn = data; + ((packet_t*)daemon->qIn)->next = packet; + daemon->qIn = packet; } } - data = 0; + // packet = 0; async = PFALSE; } if (!async) { - if (!PeekNamedPipe(h, 0, 0, 0, 0, &r)) + if (!PeekNamedPipe(pipe, 0, 0, 0, 0, &size)) NT_ERROR("PNP01"); - if (!(data = allocate_message(d,r))) + if (!(packet = packet_allocate(daemon,size))) goto co_os_daemon_thread_loop; async = PTRUE; - if (!ReadFile(h, data->data, r, 0, &overlapped)) { - r = GetLastError(); - if (r == ERROR_IO_INCOMPLETE) + if (!ReadFile(pipe, packet->message, size, 0, &overlapped)) { + code = GetLastError(); + if (code == ERROR_IO_INCOMPLETE) continue; - if (r == ERROR_IO_PENDING) + if (code == ERROR_IO_PENDING) continue; - if (r == ERROR_BROKEN_PIPE) + if (code == ERROR_BROKEN_PIPE) goto co_os_daemon_thread_broken_pipe; NT_ERROR("RF001"); } @@ -323,56 +175,47 @@ co_os_daemon_thread_return: if (async) { - CancelIo(h); - HeapFree(d->heap, HEAP_NO_SERIALIZE, data); -// co_os_free(data); + CancelIo(pipe); + HeapFree(daemon->heap, HEAP_NO_SERIALIZE, packet); async = 0; } - while (d->loop && d->qOut) { - if (!d->message) { - p = d->qOut; - if(! (d->qOut = p->next) ) - d->qIn = 0; - p->next = d->packets; - d->packets = p; - d->message = p->data; - if (!SetEvent(d->readable)) { + while (daemon->loop && daemon->qOut) { + if (!daemon->message) { + p = daemon->qOut; + if(! (daemon->qOut = p->next) ) + daemon->qIn = 0; + p->next = daemon->packets; + daemon->packets = p; + daemon->message = p->message; + // p = 0; + if (!SetEvent(daemon->readable)) { if (!CO_OK(rc)) break; NT_ERROR("SE0002"); } } - if (WaitForSingleObject(w[1], INFINITE) == WAIT_FAILED) { + if (WaitForSingleObject(events[1], INFINITE) == WAIT_FAILED) { if (!CO_OK(rc)) break; NT_ERROR("W0003"); } - if (!d->message) - if (!ResetEvent(d->readable)) { + if (!daemon->message) + if (!ResetEvent(daemon->readable)) { if (!CO_OK(rc)) break; NT_ERROR("RE0002"); } } - if(d->packets) { - data = d->packets; - do { - p = data->next; - HeapFree(d->heap, HEAP_NO_SERIALIZE, data); -// co_os_free(data); - } while( (data = p) ); - } if (overlapped.hEvent) if ((!CloseHandle(overlapped.hEvent)) && CO_OK(rc)) co_debug_lvl(pipe,1,"co_os_daemon_thread() error" " [ %x , CH0001 ]\n", GetLastError()); - d->rc = rc; - if (d->loop) - if ((!SetEvent(d->readable)) && CO_OK(rc)) + daemon->rc = rc; + if (daemon->loop) + if ((!SetEvent(daemon->readable)) && CO_OK(rc)) co_debug_lvl(pipe,1,"co_os_daemon_thread() error" " [ %x , SE0003 ]\n", GetLastError()); - HeapDestroy(d->heap); return 0; co_os_daemon_thread_error: @@ -382,22 +225,160 @@ co_os_daemon_thread_broken_pipe: rc = CO_RC(BROKEN_PIPE); goto co_os_daemon_thread_return; +} -# undef Q_REALLOC_1 -# undef Q_REALLOC_2 -# undef Q_COPY_2 -# undef NT_ERROR +co_rc_t +co_os_daemon_message_deallocate(co_daemon_handle_t daemon, co_message_t *message) +{ + packet_t *packet = (packet_t*) + ((unsigned)message - sizeof(packet_t)); + packet->free = 1; + return CO_RC(OK); } -void -co_os_daemon_close(co_daemon_handle_t D) +co_rc_t +co_os_daemon_message_receive(co_daemon_handle_t daemon, + co_message_t ** message_out, unsigned long timeout) { - D->loop = 0; - SetEvent(D->shifted); - WaitForSingleObject(D->thread, INFINITE); - CloseHandle(D->readable); - CloseHandle(D->shifted); - CloseHandle(D->handle); - CloseHandle(D->thread); - co_os_free(D); + DWORD r; + co_rc_t rc = daemon->rc; + + *message_out = NULL; + + if (daemon->message) { + *message_out = daemon->message; + daemon->message = 0; + return CO_RC(OK); + } + + if (!CO_OK(rc)) + return rc; + + SetEvent(daemon->shifted); + + r = MsgWaitForMultipleObjects(1, &daemon->readable, FALSE, timeout, + QS_ALLEVENTS); + if (r == WAIT_TIMEOUT || r == WAIT_OBJECT_0 + 1) { + return CO_RC(TIMEOUT); + } + + if (daemon->message) { + *message_out = daemon->message; + daemon->message = 0; + } + SetEvent(daemon->shifted); + + return CO_RC(OK); } + +co_rc_t +co_os_daemon_message_send(co_daemon_handle_t daemon, co_message_t * message) +{ + unsigned long bytes_written; + unsigned long bytes_to_write = sizeof (*message) + message->size; + BOOL ret; + + ret = WriteFile(daemon->handle, (char *) message, + bytes_to_write, &bytes_written, NULL); + + if (ret != TRUE) + return CO_RC(ERROR); + + if (bytes_written != bytes_to_write) + return CO_RC(ERROR); + + return CO_RC(OK); +} + +co_rc_t +co_os_daemon_pipe_open(co_id_t linux_id, co_module_t module_id, + co_daemon_handle_t * handle_out) +{ + HANDLE handle = INVALID_HANDLE_VALUE; + long written = 0; + char pathname[0x100]; + co_daemon_handle_t daemon = 0; + co_module_name_t module_name; + + snprintf(pathname, sizeof (pathname), "\\\\.\\pipe\\coLinux%d", + (int) linux_id); + + co_module_repr(module_id, &module_name); + + co_debug("connecting to instance %d as %s\n", linux_id, module_name); + + if (!WaitNamedPipe(pathname, NMPWAIT_USE_DEFAULT_WAIT)) { + co_debug("connection timed out (%x)\n", GetLastError()); + goto co_os_open_daemon_pipe_error; + } + + co_debug("connection established\n"); + + handle = CreateFile(pathname, + GENERIC_READ | GENERIC_WRITE, + 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); + + if (handle == INVALID_HANDLE_VALUE) + goto co_os_open_daemon_pipe_error; + + /* Identify ourselves to the daemon */ + if (!WriteFile(handle, &module_id, sizeof (module_id), &written, NULL)) { + co_debug("attachment failed\n"); + goto co_os_open_daemon_pipe_error; + } + + if (!(daemon = co_os_malloc(sizeof (*daemon)))) + goto co_os_open_daemon_pipe_error; + + daemon->handle = handle; + daemon->loop = 1; + daemon->rc = CO_RC(OK); + daemon->message = 0; + daemon->shifted = CreateEvent(0, FALSE, FALSE, 0); + daemon->readable = CreateEvent(0, TRUE, TRUE, 0); + if (!(daemon->shifted && daemon->readable)) + goto co_os_open_daemon_pipe_error; + + co_debug_lvl(pipe,10,"user daemon thread starting"); + daemon->thread = + CreateThread(0, 0, io_thread, daemon, 0, 0); + + if (daemon->thread) { + *handle_out = daemon; + return CO_RC(OK); + } + + co_debug("co_os_daemon_thread() did not start\n"); + + co_os_open_daemon_pipe_error: + + if (daemon) { + if (daemon->readable) + CloseHandle(daemon->readable); + if (daemon->shifted) + CloseHandle(daemon->shifted); + if (daemon->thread) + CloseHandle(daemon->thread); + co_os_free(daemon); + } + + if (handle != INVALID_HANDLE_VALUE) + CloseHandle(handle); + + return CO_RC(ERROR); +} + +co_rc_t +co_os_daemon_pipe_close(co_daemon_handle_t daemon) +{ + daemon->loop = 0; + SetEvent(daemon->shifted); + WaitForSingleObject(daemon->thread, INFINITE); + CloseHandle(daemon->readable); + CloseHandle(daemon->shifted); + CloseHandle(daemon->handle); + CloseHandle(daemon->thread); + HeapDestroy(daemon->heap); + co_os_free(daemon); + return CO_RC(OK); +} --- src/colinux/user/console-base/console.cpp +++ src/colinux/user/console-base/console.cpp @@ -1,8 +1,8 @@ /* * This source code is a part of coLinux source package. * * Dan Aloni , 2003 (c) - * Ballard, Jonathan H. , 2004 (c) + * Ballard, Jonathan H. , 2004 (c) * * The code is licensed under the GPL. See the COPYING file at * the root directory. @@ -96,7 +96,7 @@ if (state == CO_CONSOLE_STATE_ATTACHED) return CO_RC(ERROR); - rc = co_os_open_daemon_pipe(attached_id, CO_MODULE_CONSOLE, &daemon_handle); + rc = co_os_daemon_pipe_open(attached_id, CO_MODULE_CONSOLE, &daemon_handle); if (!CO_OK(rc)) return rc; @@ -164,14 +164,14 @@ message->console.size = console->size; memcpy(message->data, console, console->size); - co_os_daemon_send_message(daemon_handle, &message->message); + co_os_daemon_message_send(daemon_handle, &message->message); co_os_free(message); } co_console_unpickle(console); co_console_destroy(console); - co_os_daemon_close(daemon_handle); + co_os_daemon_pipe_close(daemon_handle); daemon_handle = 0; @@ -250,7 +250,7 @@ message->console.size = console->size; memcpy(message->data, console, console->size); - co_os_daemon_send_message(daemon_handle, + co_os_daemon_message_send(daemon_handle, &message->message); co_os_free(message); } @@ -258,7 +258,7 @@ co_console_unpickle(console); co_console_destroy(console); - co_os_daemon_close(daemon_handle); + co_os_daemon_pipe_close(daemon_handle); daemon_handle = 0; @@ -321,7 +321,7 @@ case CO_MODULE_CONSOLE:{ if (daemon_handle) - co_os_daemon_send_message(daemon_handle, + co_os_daemon_message_send(daemon_handle, &message); break; } @@ -354,7 +354,7 @@ message.linux.size = sizeof (message.code); message.code = sc; - co_os_daemon_send_message(daemon_handle, &message.message); + co_os_daemon_message_send(daemon_handle, &message.message); } void console_window_t::log(const char *format, ...) const @@ -383,7 +383,7 @@ if (daemon_handle) { co_message_t * message = NULL; - rc = co_os_daemon_get_message(daemon_handle, &message, 10); + rc = co_os_daemon_message_receive(daemon_handle, &message, 10); if (!CO_OK(rc)) { if (CO_RC_GET_CODE(rc) == CO_RC_BROKEN_PIPE) { log("Monitor%d: Broken pipe\n", attached_id); @@ -396,7 +396,7 @@ if (message) { event(*message); - co_os_daemon_deallocate_message(message); + co_os_daemon_message_deallocate(daemon_handle, message); } } --- src/colinux/user/console/console.cpp +++ src/colinux/user/console/console.cpp @@ -247,7 +247,7 @@ goto out; } - rc = co_os_open_daemon_pipe(attached_id, CO_MODULE_CONSOLE, &daemon_handle); + rc = co_os_daemon_pipe_open(attached_id, CO_MODULE_CONSOLE, &daemon_handle); if (!CO_OK(rc)) goto out; @@ -328,7 +328,7 @@ message->console.size = console->size; memcpy(message->data, console, console->size); - co_os_daemon_send_message(daemon_handle, &message->message); + co_os_daemon_message_send(daemon_handle, &message->message); co_os_free(message); } @@ -342,7 +342,7 @@ menu_item_deactivate(console_detach_cb); menu_item_activate(console_attach_cb); - co_os_daemon_close(daemon_handle); + co_os_daemon_pipe_close(daemon_handle); Fl::remove_idle(console_idle, this); @@ -375,7 +375,7 @@ message.console.type = CO_DAEMON_CONSOLE_MESSAGE_TERMINATE; message.console.size = 0; - co_os_daemon_send_message(daemon_handle, &message.message); + co_os_daemon_message_send(daemon_handle, &message.message); return detach(); } @@ -398,7 +398,7 @@ message.console.type = CO_DAEMON_CONSOLE_MESSAGE_CTRL_ALT_DEL; message.console.size = 0; - co_os_daemon_send_message(daemon_handle, &message.message); + co_os_daemon_message_send(daemon_handle, &message.message); return CO_RC(OK); } @@ -440,7 +440,7 @@ co_rc_t rc = CO_RC(OK); co_message_t *message = NULL; - rc = co_os_daemon_get_message(daemon_handle, &message, 10); + rc = co_os_daemon_message_receive(daemon_handle, &message, 10); if (!CO_OK(rc)) { if (CO_RC_GET_CODE(rc) == CO_RC_BROKEN_PIPE) { log("Monitor%d: Broken pipe\n", attached_id); @@ -451,7 +451,7 @@ if (message) { handle_message(message); - co_os_daemon_deallocate_message(message); + co_os_daemon_message_deallocate(daemon_handle, message); } } } @@ -544,7 +544,7 @@ message.msg_linux.size = sizeof(message.code); message.code = sc; - co_os_daemon_send_message(daemon_handle, &message.message); + co_os_daemon_message_send(daemon_handle, &message.message); } Fl_Menu_Item *console_window_t::find_menu_item_by_callback(Fl_Callback *cb)