From 7cba31e8f9f400d38a5f337badec726997e875ee Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Wed, 24 Jan 2018 13:29:36 +0000 Subject: [PATCH] added Socket>>writeBytes:offset:length: --- moo/kernel/Socket.moo | 10 ++++++++-- moo/lib/main.c | 4 ++-- moo/mod/sck.c | 36 ++++++++++++++++++++++++++++++++++-- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/moo/kernel/Socket.moo b/moo/kernel/Socket.moo index aad8af3..29c7a7e 100644 --- a/moo/kernel/Socket.moo +++ b/moo/kernel/Socket.moo @@ -245,6 +245,7 @@ class Socket(Object) from 'sck' method(#primitive) readBytes: bytes. method(#primitive) _writeBytes: bytes. + method(#primitive) _writeBytes: bytes offset: offset length: length. } (* TODO: generate these domain and type from the C header *) @@ -337,9 +338,11 @@ extend Socket method writeBytes: bytes { | old_output_action | + old_output_action := self.outputAction. self.outputAction := [ :sck :state | self _writeBytes: bytes. +## TODO: handle _writeBytes may not write in full. ## restore the output action block before executing the previous ## one. i don't want this action block to be chained by the @@ -348,6 +351,7 @@ extend Socket if (old_output_action notNil) { old_output_action value: self value: true }. self unwatchOutput. ]. + self watchOutput. } @@ -495,10 +499,12 @@ error -> exception ## TODO: what should it accept as block parameter ## socket, output result? , output object? outact := [:sck :state | + if (state) { - [ sck writeBytes: #[ $h, $e, $l, $l, $o, C'\n' ] ] - on: Exception do: [:ex | sck close. ]. + ## what if i want write more data??? + ##[ sck writeBytes: #[ $h, $e, $l, $l, $o, C'\n' ] ] + ## on: Exception do: [:ex | sck close. ]. } else { diff --git a/moo/lib/main.c b/moo/lib/main.c index f9036fe..038a1a2 100644 --- a/moo/lib/main.c +++ b/moo/lib/main.c @@ -859,7 +859,7 @@ static int _add_poll_fd (moo_t* moo, int fd, int event_mask) /* epoll_wait may return again if the worker thread consumes events. * switch to level-trigger. */ /* TODO: verify if EPOLLLET is desired */ - ev.events |= EPOLLET; + //ev.events |= EPOLLET; #endif /*ev.data.ptr = (void*)event_data;*/ ev.data.fd = fd; @@ -1043,7 +1043,7 @@ static int _mod_poll_fd (moo_t* moo, int fd, int event_mask) /* epoll_wait may return again if the worker thread consumes events. * switch to level-trigger. */ /* TODO: verify if EPOLLLET is desired */ - ev.events |= EPOLLET; + //ev.events |= EPOLLET; #endif ev.data.fd = fd; if (epoll_ctl (xtn->ep, EPOLL_CTL_MOD, fd, &ev) == -1) diff --git a/moo/mod/sck.c b/moo/mod/sck.c index 531aa58..132221b 100644 --- a/moo/mod/sck.c +++ b/moo/mod/sck.c @@ -413,6 +413,7 @@ static moo_pfrc_t pf_write_socket (moo_t* moo, moo_ooi_t nargs) { oop_sck_t sck; moo_oop_byte_t buf; + moo_oow_t offset, length, maxlen; int fd; ssize_t n; @@ -437,7 +438,37 @@ static moo_pfrc_t pf_write_socket (moo_t* moo, moo_ooi_t nargs) return MOO_PF_FAILURE; } - n = send (fd, MOO_OBJ_GET_BYTE_SLOT(buf), MOO_OBJ_GET_SIZE(buf), 0); + + offset = 0; + maxlen = MOO_OBJ_GET_SIZE(buf); + length = maxlen; + + if (nargs >= 2) + { + moo_oop_t tmp; + + tmp = MOO_STACK_GETARG(moo, nargs, 1); + if (moo_inttooow (moo, tmp, &offset) <= 0) + { + moo_seterrbfmt (moo, MOO_EINVAL, "invalid offset - %O", tmp); + return MOO_PF_FAILURE; + } + + if (nargs >= 3) + { + tmp = MOO_STACK_GETARG(moo, nargs, 2); + if (moo_inttooow (moo, tmp, &length) <= 0) + { + moo_seterrbfmt (moo, MOO_EINVAL, "invalid length - %O", tmp); + return MOO_PF_FAILURE; + } + } + + if (offset >= maxlen) offset = maxlen - 1; + if (length > maxlen - offset) length = maxlen - offset; + } + + n = send (fd, &MOO_OBJ_GET_BYTE_SLOT(buf)[offset], length, 0); if (n <= -1 && errno != EWOULDBLOCK) { moo_seterrwithsyserr (moo, errno); @@ -476,7 +507,8 @@ static moo_pfinfo_t pfinfos[] = { I, { 'o','p','e','n','\0' }, 0, { pf_open_socket, 3, 3 } }, { I, { 'r','e','a','d','B','y','t','e','s',':','\0' }, 0, { pf_read_socket, 1, 1 } }, { I, { 's','o','c','k','e','t','E','r','r','o','r','\0' }, 0, { pf_get_socket_error, 0, 0 } }, - { I, { 'w','r','i','t','e','B','y','t','e','s',':','\0' }, 0, { pf_write_socket, 1, 1 } } + { I, { 'w','r','i','t','e','B','y','t','e','s',':','\0' }, 0, { pf_write_socket, 1, 1 } }, + { I, { 'w','r','i','t','e','B','y','t','e','s',':','o','f','f','s','e','t',':','l','e','n','g','t','h',':','\0' }, 0, { pf_write_socket, 3, 3 } } }; /* ------------------------------------------------------------------------ */