aboutsummaryrefslogtreecommitdiff
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
parent17245cb03fb02ae9c6b0409c1e6bdb538322a498 (diff)
buffered polling tcp/ip server
-rw-r--r--compiler/elymasGlobalSysAsm.ey13
-rw-r--r--compiler/standard.ey3
-rw-r--r--elymas/lib/net/alg.ey6
-rw-r--r--elymas/lib/net/alg/server.ey123
-rw-r--r--elymas/lib/sys/linux.ey7
-rw-r--r--elymas/lib/txt.ey9
-rw-r--r--elymas/loaded.ey2
-rw-r--r--examples/working-compiler/bufferedServer.test6
8 files changed, 164 insertions, 5 deletions
diff --git a/compiler/elymasGlobalSysAsm.ey b/compiler/elymasGlobalSysAsm.ey
index 8a5499c..e9c1ad5 100644
--- a/compiler/elymasGlobalSysAsm.ey
+++ b/compiler/elymasGlobalSysAsm.ey
@@ -200,6 +200,19 @@
:retn
]] /eyrawAddress defv
+ # generate object from raw object
+ # 0 -> address of the object
+ # 0 <- object
+ [[
+ /rbx :popqReg
+
+ /rax :popqReg
+ 8 /rax :pushqMemDisp8 # push integer value
+
+ /rbx :pushqReg
+ :retn
+ ]] /eyrawObject defv
+
# get raw code execution address from function object
# 0 -> function object
# 0 <- address of first instruction
diff --git a/compiler/standard.ey b/compiler/standard.ey
index f440fb0..006414e 100644
--- a/compiler/standard.ey
+++ b/compiler/standard.ey
@@ -12,7 +12,8 @@
} "}_" defq
{
- { -01 < ==o { o -01 . } > -12 deffst }" quoted { }" { * }" ? *
+ { -01 < ==o { o -01 . } > -12 }" quoted { }" { * }" ? *
+ quoted { |deffst } { deffst }" ? *
}" /via defq
{ -1110 ; ==f =*a len _
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
diff --git a/elymas/loaded.ey b/elymas/loaded.ey
index ffe59bc..6cac2a1 100644
--- a/elymas/loaded.ey
+++ b/elymas/loaded.ey
@@ -9,6 +9,8 @@
"lib/net/tcp.ey"
"lib/net/udp.ey"
"lib/net/dns.ey"
+ "lib/net/alg.ey"
+ "lib/net/alg/server.ey"
] { _ dump include }' each
{ "/proc/self/fd/0" include }' "loaded" sys .freeze
diff --git a/examples/working-compiler/bufferedServer.test b/examples/working-compiler/bufferedServer.test
new file mode 100644
index 0000000..58e47a8
--- /dev/null
+++ b/examples/working-compiler/bufferedServer.test
@@ -0,0 +1,6 @@
+net .alg .bufferedEpollServer "+" via
+ { ":" via <
+ { :write "" } =*in
+ { :close } _ =*end =*err
+ > } +accept
+ { 2001 } +port +run