aboutsummaryrefslogtreecommitdiff
path: root/elymas/lib/net/alg
diff options
context:
space:
mode:
authorDrahflow <drahflow@gmx.de>2013-09-04 00:30:15 +0200
committerDrahflow <drahflow@gmx.de>2013-09-04 00:30:15 +0200
commit20efe1efeb3c62b884ccc16fd77e3b4c430c3ed9 (patch)
treef95adf63f534e734579ffca9e314ed94880ce572 /elymas/lib/net/alg
parent17245cb03fb02ae9c6b0409c1e6bdb538322a498 (diff)
buffered polling tcp/ip server
Diffstat (limited to 'elymas/lib/net/alg')
-rw-r--r--elymas/lib/net/alg/server.ey123
1 files changed, 123 insertions, 0 deletions
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