view 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 source

#{
	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"
		}
	}
}