diff samples/epoll.tp @ 375:f8d80c16abbd

Add epoll module and a basic epoll sample
author Michael Pavone <pavone@retrodev.com>
date Fri, 14 Aug 2015 23:08:54 -0700
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/epoll.tp	Fri Aug 14 23:08:54 2015 -0700
@@ -0,0 +1,84 @@
+#{
+	echo <- :sock {
+		print: "New connection\n"
+		data <- sock recv: 4096
+		while: { (data length) > 0 } do: {
+			sock send: data
+			data <- sock recv: 4096
+		}
+		print: "Connection closed\n"
+	}
+	continue? <- true
+	acceptHandler <- :sock ep {
+		epe <- epoll events
+		:_ {
+			(sock accept) value: :csock {
+				ep addFD: (csock fd) withMask: (epe in) data: (clientHandler: csock ep)
+			} none: {
+				print: "Failed to accept new connection\n"
+			}
+		}
+	}
+	
+	clientHandler <- :sock ep {
+		epe <- epoll events
+		_buffers <- #[]
+		waitingOut <- false
+		_me <- :eventMask {
+			if: eventMask and (epe in) != 0 {
+				_buffers append: (sock recv: 4096)
+			}
+			if: eventMask and (epe out) != 0 && (_buffers length) > 0 {
+				buf <- _buffers join: ""
+				_buffers <- #[]
+				sent <- sock send: buf
+				if: sent < (buf byte_length) {
+					_buffers append: (buf from: sent)
+				}
+			}
+			if: (_buffers length) > 0 {
+				if: (not: waitingOut) {
+					waitingOut <- true
+					ep modifyFD: (sock fd) setMask: (epe in) or (epe out) data: _me
+				}
+			} else: {
+				if: waitingOut {
+					waitingOut <- false
+					ep modifyFD: (sock fd) setMask: (epe in) data: _me
+				}
+			}
+			//TODO: Handle connection close/error
+		}
+		_me
+	}
+	
+	main <- :args {
+		port <- "2323"
+		if: (args length) > 1 {
+			port <- args get: 1
+		}
+		(socket listenOnPort: port) value: :lsock {
+			print: "Listening on port " . port . "\n"
+			
+			epe <- epoll events
+			(epoll create) value: :ep {
+				ep addFD: (lsock fd) withMask: (epe in) data: (acceptHandler: lsock ep)
+				while: { continue? } do: {
+					(ep wait: -1 maxEvents: 16) value: :events {
+						foreach: events :idx ev {
+							handler <- ev data
+							handler: (ev event)
+						}
+					} none: {
+						print: "Failed to wait for events\n"
+						continue? <- false
+					}
+				}
+			} none: {
+				print: "Failed to create epoll file descriptor"
+			}
+		} none: {
+			print: "Failed to listen on port " . port . "\n"
+		}
+	}
+}
\ No newline at end of file