Method Stdio.File()->set_write_oob_callback()

Method set_write_oob_callback

void set_read_callback(function(mixed, string:int) read_cb)
void set_write_callback(function(mixed:int) write_cb)
void set_read_oob_callback(function(mixed, string:int) read_oob_cb)
void set_write_oob_callback(function(mixed:int) write_oob_cb)
void set_close_callback(function(mixed:int) close_cb)
void set_fs_event_callback(function(mixed, int:int) fs_event_cb, int event_mask)


These functions set the various callbacks, which will be called when various events occur on the stream. A zero as argument will remove the callback.

A Pike.Backend object is responsible for calling the callbacks. It requires a thread to be waiting in it to execute the calls. That means that only one of the callbacks will be running at a time, so you don't need mutexes between them.

Unless you've specified otherwise with the set_backend function, the default backend Pike.DefaultBackend will be used. It's normally activated by returning -1 from the main function and will then execute in the main thread.

  • When data arrives on the stream, read_cb will be called with some or all of that data as the second argument.

  • When the stream has buffer space over for writing, write_cb will be called so that you can write more data to it.

    This callback is also called after the remote end of a socket connection has closed the write direction. An attempt to write data to it in that case will generate a System.EPIPE errno. If the remote end has closed both directions simultaneously (the usual case), Pike will first attempt to call close_cb, then this callback (unless close_cb has closed the stream).

  • When out-of-band data arrives on the stream, read_oob_cb will be called with some or all of that data as the second argument.

  • When the stream allows out-of-band data to be sent, write_oob_cb will be called so that you can write more out-of-band data to it.

    If the OS doesn't separate the write events for normal and out-of-band data, Pike will try to call write_oob_cb first. If it doesn't write anything, then write_cb will be tried. This also means that write_oob_cb might get called when the remote end of a connection has closed the write direction.

  • When an error or an end-of-stream in the read direction occurs, close_cb will be called. errno will return the error, or zero in the case of an end-of-stream.

    The name of this callback is rather unfortunate since it really has nothing to do with a close: The stream is still open when close_cb is called (you might not be able to read and/or write to it, but you can still use things like query_address, and the underlying file descriptor is still allocated). Also, this callback will not be called for a local close, neither by a call to close or by destructing this object.

    Also, close_cb will not be called if a remote close only occurs in the write direction; that is handled by write_cb (or possibly write_oob_cb).

    Events to read_cb and close_cb will be automatically deregistered if an end-of-stream occurs, and all events in the case of an error. I.e. there won't be any more calls to the callbacks unless they are reinstalled. This doesn't affect the callback settings - query_read_callback et al will still return the installed callbacks.

If the stream is a socket performing a nonblocking connect (see open_socket and connect), a connection failure will call close_cb, and a successful connect will call either read_cb or write_cb as above.

All callbacks will receive the id set by set_id as first argument.

If a callback returns -1, no other callback or call out will be called by the backend in that round. I.e. the caller of the backend will get control back right away. For the default backend that means it will immediately start another round and check files and call outs anew.

Parameter event_mask

An event mask specifing bitwise OR of one or more event types to monitor, selected from Stdio.NOTE_WRITE and friends.


These functions do not set the file nonblocking.


Callbacks are also set by set_callbacks and set_nonblocking().


After a callback has been called, it's disabled until it has accessed the stream accordingly, i.e. the write_cb callback is disabled after it's been called until something has been written with write, and the write_oob_cb callback is likewise disabled until something has been written with write_oob. Since the data already has been read when the read callbacks are called, this effect is not noticeable for them.


Installing callbacks means that you will start doing I/O on the stream from the thread running the backend. If you are running these set functions from another thread you must be prepared that the callbacks can be called immediately by the backend thread, so it might not be safe to continue using the stream in this thread.

Because of that, it's useful to talk about "callback mode" when any callback is installed. In callback mode the stream should be seen as "bound" to the backend thread. For instance, it's only the backend thread that reliably can end callback mode before the stream is "handed over" to another thread.


Callback mode has nothing to do with nonblocking mode - although the two often are used together they don't have to be.


The file object will stay referenced from the backend object as long as there are callbacks that can receive events.


Setting a close callback without a read callback currently only works when there's no risk of getting more data on the stream. Otherwise the close callback will be silently deregistered if data arrives.


fs_event callbacks only trigger on systems that support these events. Currently, this includes systems that use kqueue, such as Mac OS X, and various flavours of BSD.

See also

set_callbacks, set_nonblocking(), set_id(), set_backend, query_read_callback, query_write_callback, query_read_oob_callback, query_write_oob_callback, query_close_callback