host = null
end
+ # Returns an array containing an enum of the events ready to be read
+ #
+ # event_types : Combination of several event types to watch
+ #
+ # timeout : Time in milliseconds before stopping listening for events on this socket
+ #
+ private fun poll_in(event_types: Array[FFSocketPollValues], timeout: Int): Array[FFSocketPollValues] do return socket.socket_poll(new PollFD(socket.descriptor, event_types), timeout)
+
+ # Easier use of poll_in to check for something to read on all channels of any priority
+ #
+ # timeout : Time in milliseconds before stopping to wait for events
+ #
+ fun ready_to_read(timeout: Int): Bool
+ do
+ var events = new Array[FFSocketPollValues]
+ events.push(new FFSocketPollValues.pollin)
+ events.push(new FFSocketPollValues.pollrdnorm)
+ events.push(new FFSocketPollValues.pollpri)
+ events.push(new FFSocketPollValues.pollrdband)
+ return poll_in(events, timeout).length != 0
+ end
+
+ # Checks if the socket still is connected
+ #
+ fun connected: Bool
+ do
+ var events = new Array[FFSocketPollValues]
+ events.push(new FFSocketPollValues.pollhup)
+ events.push(new FFSocketPollValues.pollerr)
+ return poll_in(events, 0).length == 0
+ end
+
fun connect: Bool do return socket.connect(addrin) >= 0
fun write(msg: String): Bool do return socket.write(msg) >= 0
fun read: String do return socket.read
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
+ #include <sys/poll.h>
#include <errno.h>
typedef int S_DESCRIPTOR;
typedef socklen_t S_LEN;
`}
+# Wrapper for the data structure PollFD used for polling on a socket
+class PollFD
+
+ # The PollFD object
+ private var poll_struct: FFSocketPollFD
+
+ # A collection of the events to be watched
+ var events: Array[FFSocketPollValues]
+
+ init(pid: Int, events: Array[FFSocketPollValues])
+ do
+ assert events.length >= 1
+ self.events = events
+
+ var events_in_one = events[0]
+
+ for i in [1 .. events.length-1] do
+ events_in_one += events[i]
+ end
+
+ self.poll_struct = new FFSocketPollFD(pid, events_in_one)
+ end
+
+ # Reads the response and returns an array with the type of events that have been found
+ private fun check_response(response: Int): Array[FFSocketPollValues]
+ do
+ var resp_array = new Array[FFSocketPollValues]
+ for i in events do
+ if c_check_resp(response, i) != 0 then
+ resp_array.push(i)
+ end
+ end
+ return resp_array
+ end
+
+ # Checks if the poll call has returned true for a particular type of event
+ private fun c_check_resp(response: Int, mask: FFSocketPollValues): Int
+ `{
+ return response & mask;
+ `}
+
+end
+
+# Data structure used by the poll function
+private extern FFSocketPollFD `{ struct pollfd `}
+ # File descriptor id
+ private fun fd: Int `{ return recv.fd; `}
+ # List of events to be watched
+ private fun events: Int `{ return recv.events; `}
+ # List of events received by the last poll function
+ private fun revents: Int `{ return recv.revents; `}
+
+ new (pid: Int, events: FFSocketPollValues) `{
+ struct pollfd poll;
+ poll.fd = pid;
+ poll.events = events;
+ return poll;
+ `}
+
+end
+
extern FFSocket `{ S_DESCRIPTOR* `}
new socket(domain: FFSocketAddressFamilies, socketType: FFSocketTypes, protocol: FFSocketProtocolFamilies) `{
S_DESCRIPTOR *d = NULL; d = (S_DESCRIPTOR*) malloc( sizeof(S_DESCRIPTOR) );
fun bind(addrIn: FFSocketAddrIn): Int `{ return bind(*recv, (S_ADDR*)addrIn, sizeof(*addrIn)); `}
fun listen(size: Int): Int `{ return listen(*recv, size); `}
+ # Checks if the buffer is ready for any event specified when creating the pollfd structure
+ fun socket_poll(filedesc: PollFD, timeout: Int): Array[FFSocketPollValues]
+ do
+ var result = i_poll(filedesc.poll_struct, timeout)
+ assert result != -1
+ return filedesc.check_response(result)
+ end
+
+ # Call to the poll function of the C socket
+ #
+ # Signature :
+ # int poll(struct pollfd fds[], nfds_t nfds, int timeout);
+ #
+ # Official documentation of the poll function :
+ #
+ # The poll() function provides applications with a mechanism for multiplexing input/output over a set of file descriptors.
+ # For each member of the array pointed to by fds, poll() shall examine the given file descriptor for the event(s) specified in events.
+ # The number of pollfd structures in the fds array is specified by nfds.
+ # The poll() function shall identify those file descriptors on which an application can read or write data, or on which certain events have occurred.
+ # The fds argument specifies the file descriptors to be examined and the events of interest for each file descriptor.
+ # It is a pointer to an array with one member for each open file descriptor of interest.
+ # The array's members are pollfd structures within which fd specifies an open file descriptor and events and revents are bitmasks constructed by
+ # OR'ing a combination of the pollfd flags.
+ private fun i_poll(filedesc: FFSocketPollFD, timeout: Int): Int `{
+ int poll_return = poll(&filedesc, 1, timeout);
+ return poll_return;
+ `}
+
private fun i_accept(addrIn: FFSocketAddrIn): FFSocket `{
S_LEN s = sizeof(S_ADDR);
S_DESCRIPTOR *d = NULL;
new pf_max `{ return PF_MAX; `}
end
+# Used for the poll function of a socket, mix several Poll values to check for events on more than one type of event
+extern FFSocketPollValues `{ int `}
+ new pollin `{ return POLLIN; `} # Data other than high-priority data may be read without blocking.
+ new pollrdnorm `{ return POLLRDNORM; `} # Normal data may be read without blocking.
+ new pollrdband `{ return POLLRDBAND; `} # Priority data may be read without blocking.
+ new pollpri `{ return POLLPRI; `} # High-priority data may be read without blocking.
+ new pollout `{ return POLLOUT; `} # Normal data may be written without blocking.
+ new pollwrnorm `{ return POLLWRNORM; `} # Equivalent to POLLOUT
+ new pollwrband `{ return POLLWRBAND; `} # Priority data may be written.
+ new pollerr `{ return POLLERR; `} # An error has occurred on the device or stream. This flag is only valid in the revents bitmask; it shall be ignored in the events member.
+ new pollhup `{ return POLLHUP; `} # The device has been disconnected. This event and POLLOUT are mutually-exclusive; a stream can never be writable if a hangup has occurred. However, this event and POLLIN, POLLRDNORM, POLLRDBAND, or POLLPRI are not mutually-exclusive. This flag is only valid in the revents bitmask; it shall be ignored in the events member.
+ new pollnval `{ return POLLNVAL; `} # The specified fd value is invalid. This flag is only valid in the revents member; it shall ignored in the events member.
+
+ # Combines two FFSocketPollValues
+ private fun +(other: FFSocketPollValues): FFSocketPollValues `{
+ return recv | other;
+ `}
+end