Closed jmalloc closed 8 years ago
The implementation of this is proving a little complex in ReactApi
. Because it's driven by callbacks, only a single stream is ever returned to any given strand. This might mean that if the same streams are read inside a loop only then the order in the array becomes like somewhat of a priority - if this is the case then perhaps some form of randomisation is required. Likewise, if a given strand is waiting on both readable and writable streams, it might always favour the readable ones (as their callbacks are registered with React before the writable ones). None of these things should be an issue with the "native" implementation (#85).
@ezzatron, @koden-km - I'd appreciate a proof-reading of the docblocks for read()
, write()
and select()
as of e6b72cbc. Bare in mind this is the internals of the kernel API, so where the docs say "the calling strand is resumed with x
", that approximates to "this operation returns x
" when the operation is invoked from userland via Recoil::<operation>()
.
This came together quite nicely now. The React implementation is based on StreamQueue
which provides synchronisation when several strands are using the same streams.
TODO:
select()
- ensure timeout timer is cancelled when the calling strand is terminated (func. test)read()
- resume the calling strand with an appropriate exception when fread()
returns false
read()
- the default values should read the entire stream contents (equiv. to file_get_contents()
).write()
- resume the calling strand with an appropriate exception when fwrite()
returns false
Currently, the only stream related operations in the kernel API are
read()
andwrite()
, which are essentially the same as\fread()
and\fwrite()
, except that they allow other strands to execute while waiting for stream activity.While these methods are useful, they do have some limitations:
To address these issues, I think it best thatread()
andwrite()
are removed from the kernel API entirely, and replaced with a singleselect()
operation.(1) can be solved by the addition of
Api::select()
, which would essentially be analogous to\stream_select()
but allowing other strands to execute in the meantime. Multiple strands can wait for the same streams, but only one of them is resumed when the stream becomes ready.select()
would also be used for channels when they are reimplemented, allowing a strand to wait for any combination of streams or channels(perhaps strands could use a FIFO to signal the underlying event-loop when they are ready)Guh, this is not necessary.(2) can be solved by changing the
read()
andwrite()
implementations to convenience methods for reading and writing until the buffer is filled or drained, respectively. Additionally, these methods could also "lock" the individual streams so that no other strands that are usingselect()
,read()
orwrite()
can "interject" and read/write data from/to the middle of the buffer. The existing functionality can be obtained by usingselect()
followed by\fread()
and/or\fwrite()
as appropriate.I think this will make for a very usable interface for the common case, without sacrificing any flexibility.