diff options
| author | Drahflow <drahflow@gmx.de> | 2013-09-04 00:30:15 +0200 |
|---|---|---|
| committer | Drahflow <drahflow@gmx.de> | 2013-09-04 00:30:15 +0200 |
| commit | 20efe1efeb3c62b884ccc16fd77e3b4c430c3ed9 (patch) | |
| tree | f95adf63f534e734579ffca9e314ed94880ce572 /elymas/lib | |
| parent | 17245cb03fb02ae9c6b0409c1e6bdb538322a498 (diff) | |
buffered polling tcp/ip server
Diffstat (limited to 'elymas/lib')
| -rw-r--r-- | elymas/lib/net/alg.ey | 6 | ||||
| -rw-r--r-- | elymas/lib/net/alg/server.ey | 123 | ||||
| -rw-r--r-- | elymas/lib/sys/linux.ey | 7 | ||||
| -rw-r--r-- | elymas/lib/txt.ey | 9 |
4 files changed, 141 insertions, 4 deletions
diff --git a/elymas/lib/net/alg.ey b/elymas/lib/net/alg.ey new file mode 100644 index 0000000..7fdee8b --- /dev/null +++ b/elymas/lib/net/alg.ey @@ -0,0 +1,6 @@ +< + { =*? }' /deff deffd + { ==? }' /defv deffd +> /alg net .defv + +# vim: syn=elymas diff --git a/elymas/lib/net/alg/server.ey b/elymas/lib/net/alg/server.ey new file mode 100644 index 0000000..9935016 --- /dev/null +++ b/elymas/lib/net/alg/server.ey @@ -0,0 +1,123 @@ +# provide a standard epoll-based tcp/ip server +{ < + < + { 1 } /running deffst + { 1000000 } /interval deffst + { "unconfigured accept (of epollServer)" die } /accept deffst + { "unconfigured port (of epollServer)" die } /port deffst + + { = }' /set deffst + { scope keys }' /setters deffst + { =*install + setters { _ { set }_ -01 install }" each + } /installSetters deffst + > _ ==settings "::" via + + { -1010 deffst = }' ::installSetters # TODO: def??? should overwrite existing values + + sys .linux "+" via +epoll "++" via + net .tcp "+:" via + + < + { "noHandler .in" die } =*in + { "noHandler .out" die } =*out + { "noHandler .err" die } =*err + > ==noHandler + + < + { txt .produce .u defvst }' /add deffst # TODO: possibly do it without text conversion one day + { noHandler -01 add }' /remove deffst + > ==eventHandlers + + { + ::port +:listenFd ==listenFd + + < + { + listenFd +:acceptFd ==fd + epoll ++EPOLLCTLADD fd ++EPOLLIN ++EPOLLERR bor fd ++ctl + < + { + epoll ++EPOLLCTLDEL fd 0 0 ++ctl + fd eventHandlers .remove + fd +close + } /close deffst + { ==count + count str .alloc ==buf + fd buf count +read + _ 0 lt { "read failed" die } rep # TODO: real error handling + buf str .inplacePrefix + } /read deff + { ==buf + fd buf _ len +write + _ 0 lt { "write failed" die } rep # TODO: real error handling + } /write deff + { ==flags + epoll ++EPOLLCTLMOD fd flags fd ++ctl + } /ctl deffst + > ::accept fd eventHandlers .add + } =*in + { "unexpected output capability on listening socket" die } =*out + { "error on main server socket" die } =*err + > listenFd eventHandlers .add + + ++create ==epoll + epoll ++EPOLLCTLADD listenFd ++EPOLLIN listenFd ++ctl + + { ::running } { + epoll 16 ::interval ++wait -- # TODO: error handling + { + _ .data txt .produce .u eventHandlers -01 . ":" via # TODO: consider saving raw addresses in the epoll data instead + .events + _ ++EPOLLIN band not not { :in } rep + _ ++EPOLLOUT band not not { :out } rep + ++EPOLLERR band not not { :err } rep + } each + } loop + } /run deffst +> } /epollServer net .alg .deff + +{ < + net .alg .epollServer "^" via + + < + { "unconfigured accept (of bufferedEpollServer)" die } /accept deffst + + { = }' /set deffst + { scope keys }' /setters deffst + { _ ^settings .installSetters =*install + setters { _ { set }_ -01 install }" each + } /installSetters deffst + > _ ==settings "::" via + + { -1010 deffst = }' ::installSetters # TODO: def??? should overwrite existing values + + sys .linux .epoll "++" via + + { ":" via "" ==inBuffer "" ==outBuffer + < + { + outBuffer -01 cat =outBuffer + ++EPOLLOUT ++EPOLLIN ++EPOLLERR bor bor :ctl + } =*write + { :close } =*close + > ::accept ":::" via < + { + 4096 :read _ len + { inBuffer -01 cat :::in =inBuffer } + { -- :::end } + ? * + } =*in + { + outBuffer _ :write -01 str .postfix + _ =outBuffer + len { ++EPOLLOUT } { 0 } ? * ++EPOLLIN ++EPOLLERR bor bor :ctl + } =*out + { :::err } =*err + > + } ^accept + + { ^run } /run deffst +> } /bufferedEpollServer net .alg .deff + +# vim: syn=elymas diff --git a/elymas/lib/sys/linux.ey b/elymas/lib/sys/linux.ey index 0c00fc9..f672c8d 100644 --- a/elymas/lib/sys/linux.ey +++ b/elymas/lib/sys/linux.ey @@ -359,8 +359,9 @@ # 0 -> callback data # 1 -> event mask - # 2 -> fd to add - # 3 -> epoll fd + # 2 -> fd to modify + # 3 -> what to do (i.e. EPOLLCTLADD and friends) + # 4 -> epoll fd # 0 <- raw return value { ==callbackData ==eventMask ==fd ==action ==epollFd # struct epoll_event takes 16 bytes on a x86 @@ -384,7 +385,7 @@ [ buf ret { < ->u64 ==events ->u64 ==data - > } rep -- ] + > -01 } rep -- ] ret } /wait deffd > /epoll defvd diff --git a/elymas/lib/txt.ey b/elymas/lib/txt.ey index b3bc361..847b045 100644 --- a/elymas/lib/txt.ey +++ b/elymas/lib/txt.ey @@ -2,11 +2,18 @@ < # 0 -> string # 0 <- leading digits converted to int (0, if none) - # 1 <- rest of string { "^(\\d*)" regex -- ==n [ n { 48 sub } each ] reverse 10 math .unbase } /u deffd > /consume defvd + + < + # 0 -> positive integer + # 0 <- decimal representation as string + { + [ -01 10 math .base reverse "0123456789" each ] str .fromArray + } /u deffd + > /produce defvd > /txt defvd # vim: syn=elymas |
