Tags: msantos/inert
Tags
examples: error handling to prevent leaking fd's Example code that dispenses with error handling to keep things simple is evil. Easiest change here was to use try/catch/after but other options are to use a gen_server terminate callback, a monitor process, put the fd in an NIF resource, ...
Lock file descriptors to the caller For Erlang processes, file descriptors act like global variables since they are assigned to the runtime Unix process rather than to an Erlang process. The outcome for inert is that multiple concurrent Erlang processes may accidentally register a file descriptor for events. The last process to register the fd wins. The other processes may hang waiting for events (for example, if they called inert:poll/1,2). The Erlang runtime solves this problem by encapsulating the fd in a port and sending messages to the Erlang process. inert could do something similar: return a new port each time fdset is called and allow Erlang's port ownership control the fd. Maybe this is the way inert will end up handling fd's (one port per file descriptor). This change associates an fd with an Erlang process until the next event on the file descriptor. The lock occurs when the process calls fdset, so the operation is atomic (no race between lock and set). The fd is unlocked when: * an event occurs on the fd * any process calls fdclr on the fd * the process owning the fd exits To release the fd when the process crashes, the port driver monitors the erlang process. For simplicity, monitoring is done in a stateless way: * for each fd a process polls, a new monitor is created * each time fdset for a particular fd is called, the old monitor is destroyed and a new monitor created * after an fd event, the monitor is removed * on process exit, if any monitors exist, the complete fd array is iterated through and the process PID removed The result is that the process exit callback may be called multiple times on process exit, if the process is polling multiple file descriptors. If a fd is locked by another process, the caller will receive {error,ebusy} as a reply. If a process performs an fdclr while another process is blocking in poll/1,2, the polling process will hang forever. Some future changes might be: * send a message to the owning process when another process clears the fd * send a signal to the owning process when another process clears the fd * add a new operation to test if the fd is owned by another process