Skip to content

Instantly share code, notes, and snippets.

@cheery
Last active December 25, 2016 17:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cheery/4013e906dca0de4a198737721d1c2798 to your computer and use it in GitHub Desktop.
Save cheery/4013e906dca0de4a198737721d1c2798 to your computer and use it in GitHub Desktop.
If linux had this...
// Windows has this I/O completion model where
// you get an event into a queue after completion
// of an event.
// The model is brilliant, but Windows API is cluttered
// pile of shit.
// Currently on Linux, you can use eventfd/socketpair, in
// combination with select,epoll and O_NONBLOCK flag on sockets
// to make yourself an eventloop in Linux. These inform
// the eventloop when a file descriptor is ready for read/write.
// Eventfd can be used to create a file handle where a working
// process can write to inform an another that it completed a task.
// According to libuv author http://blog.libtorrent.org/2012/10/asynchronous-disk-io/
// file reads/writes go into separate thread because
// they do not obey the nonblock flag.
// The way how Linux eventloop works is practically opposite in model
// to what's being done on Windows. And I think the Windows model,
// where every call is async and that report their completions to a
// queue could be much nicer to work with than the current combinations
// of existing Linux models.
// Here's what you would really need for it, and nothing more.
// Every iocp would return an int for error messages.
// iocp queue would be kernel-supported, and each thread
// in a process would have one.
int iocp(int cmd, void *data, void *event);
// Makes an iocp request.
// Intended to be used for doing asynchronous linux calls.
// cmd: identifies which request to do.
// data: pointer to data record of the request
// the data record is copied by the kernel
// and can be discarded immediately after the call.
// event: if NULL, the request runs synchronously.
// otherwise the event pointer will be used to
// notify completion at iocp_wait.
int iocp_notify(pthread_t thread, int status, void *event);
// Makes an iocp notification to an other thread.
// For example, to inform another thread from completion of a task.
// It is expected that the thread passes an event that is available
// to the recipient.
// Here's an example structure of data passable to iocp() call.
typedef struct {
int fd;
const void *buf;
size_t *count;
} iocp_write_t;
/* Example call:
size_t count = 10;
iocp_write_t write = {
my_fd,
"some data\n",
&count
};
res = iocp(io, IOCP_WRITE, &write, NULL);
*/
int iocp_wait(int *status, void **event, uint64_t timeout);
// Waits for an iocp event.
// status: 0 if the event indicates a success, otherwise an error status code for an event.
// event: pointer to the user defined event record. The kernel does not
// examine the contents of the pointer.
// timeout: if 0, the iocp_wait is non-blocking.
// if -1, the iocp_wait does not timeout.
// otherwise the number of milliseconds until timeout.
// Returns ETIMEOUT if timeout occurs before an event is received.
// In case of any other result than success, content of fields
// passed as arguments are undefined and they should not be used.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment