Serene Runtime 1.0.0-dev
C runtime for the Serene programming language
Loading...
Searching...
No Matches
io.h File Reference

The fiber facing IO API: blocking looking calls a fiber uses to do IO. More...

#include <stddef.h>
#include <stdint.h>
#include <sys/socket.h>
#include <sys/types.h>
#include "serene/rt/errors.h"
Include dependency graph for io.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  srn_io_fd_result_t
 The result of an op that yields a descriptor (srn_fiber_socket, srn_fiber_open). More...
struct  srn_io_size_result_t
 The result of a byte transfer op (read/write/sendto/recvmsg/sendmsg). More...
struct  srn_io_accept_result_t
 The result of srn_fiber_accept. More...
struct  srn_io_recvfrom_result_t
 The result of srn_fiber_recvfrom. More...

Macros

#define SRN_WITH_RETRY(err, ...)
 Run block and retry it (yielding between attempts through srn_fiber_io_retry) while err holds the transient CHANNEL_BUSY error.

Typedefs

typedef struct srn_io_fd_result_t srn_io_fd_result_t
 The result of an op that yields a descriptor (srn_fiber_socket, srn_fiber_open).
typedef struct srn_io_size_result_t srn_io_size_result_t
 The result of a byte transfer op (read/write/sendto/recvmsg/sendmsg).
typedef struct srn_io_accept_result_t srn_io_accept_result_t
 The result of srn_fiber_accept.
typedef struct srn_io_recvfrom_result_t srn_io_recvfrom_result_t
 The result of srn_fiber_recvfrom.

Functions

bool srn_fiber_io_retry (srn_error_t *e)
 Whether a suspending IO call should be retried, true exactly when e is the transient CHANNEL_BUSY error, in which case the calling fiber yields first so its worker can consume completions (which is what reopens the channel's admission window) and run other fibers before the retry.
srn_io_size_result_t srn_fiber_read (int fd, void *buf, size_t len, int64_t offset)
 Read up to len bytes from fd into buf, suspending the calling fiber until the operation completes rather than blocking its worker.
srn_io_size_result_t srn_fiber_write (int fd, const void *buf, size_t len, int64_t offset)
 Write len bytes from buf to fd, suspending the calling fiber until the operation completes rather than blocking its worker.
srn_error_tsrn_fiber_sleep_ns (uint64_t duration_ns)
 Suspend the calling fiber for at least duration_ns nanoseconds, letting its worker run other fibers meanwhile.
srn_error_tsrn_fiber_sleep_us (uint64_t duration_us)
 Suspend the calling fiber for at least duration_us microseconds, letting its worker run other fibers meanwhile.
srn_error_tsrn_fiber_sleep_ms (uint64_t duration_ms)
 Suspend the calling fiber for at least duration_ms miliseconds, letting its worker run other fibers meanwhile.
srn_error_tsrn_fiber_sleep (uint64_t duration)
 Suspend the calling fiber for at least duration seconds, letting its worker run other fibers meanwhile.
srn_io_accept_result_t srn_fiber_accept (int fd, struct sockaddr *addr, socklen_t addr_cap)
 Accept a pending connection on the listening socket fd, suspending the calling fiber until one arrives.
srn_error_tsrn_fiber_connect (int fd, const struct sockaddr *addr, socklen_t addrlen)
 Connect the socket fd to addr/addrlen, suspending the calling fiber until the connection completes rather than blocking its worker.
srn_io_recvfrom_result_t srn_fiber_recvfrom (int fd, void *buf, size_t len, int flags, struct sockaddr *addr, socklen_t addr_cap)
 Receive a datagram from fd into buf/len with flags (the MSG_* flags), suspending the calling fiber until one arrives.
srn_io_size_result_t srn_fiber_sendto (int fd, const void *buf, size_t len, int flags, const struct sockaddr *addr, socklen_t addrlen)
 Send buf/len on fd to addr/addrlen with flags (the MSG_* flags), suspending the calling fiber until the send completes rather than blocking its worker.
srn_io_size_result_t srn_fiber_recvmsg (int fd, struct msghdr *msg, int flags)
 Receive into the struct msghdr msg on fd with flags, suspending the calling fiber until data arrives.
srn_io_size_result_t srn_fiber_sendmsg (int fd, const struct msghdr *msg, int flags)
 Send the struct msghdr msg on fd with flags, suspending the calling fiber until the send completes.
srn_io_fd_result_t srn_fiber_socket (int domain, int type, int protocol)
 Create a socket, like socket(2), additionally forcing SOCK_NONBLOCK and SOCK_CLOEXEC so the descriptor is safe to hand to the suspending calls (a blocking socket would stall the reactor thread).
srn_error_tsrn_fiber_bind (int fd, const struct sockaddr *addr, socklen_t addrlen)
 Bind fd to addr/addrlen, like bind(2).
srn_error_tsrn_fiber_listen (int fd, int backlog)
 Mark fd as a listening socket with the given backlog, like listen(2).
srn_error_tsrn_fiber_close (int fd)
 Close fd, like close(2).
srn_error_tsrn_fiber_shutdown (int fd, int how)
 Shut down part or all of the connection on fd (how is SHUT_RD/SHUT_WR/ SHUT_RDWR), like shutdown(2).
srn_error_tsrn_fiber_getsockopt (int fd, int level, int optname, void *optval, socklen_t *optlen)
 Read a socket option into optval/optlen, like getsockopt(2).
srn_error_tsrn_fiber_setsockopt (int fd, int level, int optname, const void *optval, socklen_t optlen)
 Set a socket option from optval/optlen, like setsockopt(2).
srn_io_fd_result_t srn_fiber_open (const char *path, int flags, mode_t mode)
 Open path, like open(2), additionally forcing O_NONBLOCK and O_CLOEXEC so the descriptor is always safe to hand to the suspending calls above.

Detailed Description

The fiber facing IO API: blocking looking calls a fiber uses to do IO.

Each call builds a request, suspends the calling fiber, and hands the request to the reactor; the fiber resumes with the result once the operation completes. The calling worker is never blocked – it runs other fibers while this one is parked. These are the fiber world replacements for the raw read/write and other similar IO related syscalls.

Each call returns a small per-op result which is a fallible value (see errors.h): maybe_error is null on success and carries the failure otherwise, so the success fields are meaningful only when there is no error. Calls with no value to report (connect, sleep) return srn_error_t * directly – null on success.

Constraints: a suspending call must run on a fiber that is on a worker (it suspends the fiber, so there must be one). A pollable, non-blocking descriptor (socket, pipe, ...) goes through the reactor; a regular file is served by a synchronous syscall on the worker, since a readiness backend cannot poll it.

Backpressure: a channel admits at most one ring's worth of operations in flight, and a suspending call past that cap fails with the transient CHANNEL_BUSY error. SRN_WITH_RETRY wraps a block in the retry loop (yielding between attempts through srn_fiber_io_retry):

 srn_io_size_result_t r;
 SRN_WITH_RETRY(r.maybe_error, {
   r = srn_fiber_read(fd, buf, len, -1);
 });

At the end of this file there are a set of convenient non-suspending helpers (socket, bind, listen, close, shutdown, getsockopt, setsockopt, open), thin wrappers over the plain syscalls that share the same fallible result convention. They do not touch the reactor and may be called from any context. socket and open force O_NONBLOCK/O_CLOEXEC so a descriptor handed to the suspending calls above is always safe for the reactor.

Definition in file io.h.

Macro Definition Documentation

◆ SRN_WITH_RETRY

#define SRN_WITH_RETRY ( err,
... )
Value:
do \
__VA_ARGS__ \
while (srn_fiber_io_retry(err))
bool srn_fiber_io_retry(srn_error_t *e)
Whether a suspending IO call should be retried, true exactly when e is the transient CHANNEL_BUSY err...
Definition io.c:261

Run block and retry it (yielding between attempts through srn_fiber_io_retry) while err holds the transient CHANNEL_BUSY error.

err is the error lvalue the block assigns, r.maybe_error for a fallible result struct, the variable itself for a plain srn_error_t *. Variadic so commas inside the block do not split the arguments.

srn_io_size_result_t r;
SRN_WITH_RETRY(r.maybe_error, {
  r = srn_fiber_read(fd, buf, len, -1);
});

srn_error_t *e;
SRN_WITH_RETRY(e, { e = srn_fiber_sleep(duration); });

Definition at line 132 of file io.h.

132#define SRN_WITH_RETRY(err, ...) \
133 do \
134 __VA_ARGS__ \
135 while (srn_fiber_io_retry(err))

Typedef Documentation

◆ srn_io_accept_result_t

typedef struct srn_io_accept_result_t srn_io_accept_result_t

The result of srn_fiber_accept.

On success fd is the accepted descriptor and, when an address buffer was given, addrlen is the length of the peer address written into it.

◆ srn_io_fd_result_t

typedef struct srn_io_fd_result_t srn_io_fd_result_t

The result of an op that yields a descriptor (srn_fiber_socket, srn_fiber_open).

On success fd is the descriptor; on failure maybe_error is set.

◆ srn_io_recvfrom_result_t

typedef struct srn_io_recvfrom_result_t srn_io_recvfrom_result_t

The result of srn_fiber_recvfrom.

On success count is the number of bytes received and, when an address buffer was given, addrlen is the length of the sender address written into it.

◆ srn_io_size_result_t

typedef struct srn_io_size_result_t srn_io_size_result_t

The result of a byte transfer op (read/write/sendto/recvmsg/sendmsg).

On success count is the number of bytes moved, on failure maybe_error is set and count is unspecified.

Function Documentation

◆ srn_fiber_accept()

srn_io_accept_result_t srn_fiber_accept ( int fd,
struct sockaddr * addr,
socklen_t addr_cap )

Accept a pending connection on the listening socket fd, suspending the calling fiber until one arrives.

When addr is non-null the peer address is written into it, up to addr_cap bytes, and the result's addrlen reports how many were written. The accepted socket is created non-blocking and close on exec, so it is ready for further fiber IO. On success the result's fd is the accepted descriptor. Must run on a fiber that is on a worker.

Definition at line 327 of file io.c.

327 {
328#ifdef __linux__
329 // Force the accepted socket non-blocking and close-on-exec, so further fiber
330 // IO on it never blocks the reactor thread and it does not leak across exec.
333 .fd = fd,
334 .addr = addr,
335 .addrlen = (uint32_t)addr_cap,
336 .flags = SOCK_NONBLOCK | SOCK_CLOEXEC,
337 };
338 io_waiter_t w = io_wait(req);
339 return (srn_io_accept_result_t){
340 .maybe_error = w.maybe_error,
341 .fd = (int)w.result,
342 .addrlen = (socklen_t)w.addrlen,
343 };
344#else
345# error "You need to patch srn_fiber_accept for this platform"
346#endif
347}
static io_waiter_t io_wait(srn_reactor_io_request_t request)
The general submit path, build the request on the calling fiber's stack, submit it as the fiber parks...
Definition io.c:217
@ SRN_REACTOR_IO_ACCEPT
Accept a pending connection on the listening socket fd, with flags (the accept4 flags).
Definition reactor.h:82
Lives on the suspended fiber's stack; the worker fills it from the completion and the fiber reads it ...
Definition io.c:66
uint32_t addrlen
Definition io.c:70
size_t result
Definition io.c:69
The result of srn_fiber_accept.
Definition io.h:86
A submission, one request a fiber places on its channel.
Definition reactor.h:116
Here is the call graph for this function:
Here is the caller graph for this function:

◆ srn_fiber_bind()

srn_error_t * srn_fiber_bind ( int fd,
const struct sockaddr * addr,
socklen_t addrlen )

Bind fd to addr/addrlen, like bind(2).

Returns null on success, or the error.

Definition at line 454 of file io.c.

454 {
455#ifdef __linux__
456 return io_status(bind(fd, addr, addrlen));
457#else
458# error "You need to patch srn_fiber_bind for this platform"
459#endif
460}
static srn_error_t * io_status(int rc)
Definition io.c:424
Here is the call graph for this function:

◆ srn_fiber_close()

srn_error_t * srn_fiber_close ( int fd)

Close fd, like close(2).

Returns null on success, or the error.

Definition at line 470 of file io.c.

470 {
471#ifdef __linux__
472 return io_status(close(fd));
473#else
474# error "You need to patch srn_fiber_close for this platform"
475#endif
476}
Here is the call graph for this function:

◆ srn_fiber_connect()

srn_error_t * srn_fiber_connect ( int fd,
const struct sockaddr * addr,
socklen_t addrlen )

Connect the socket fd to addr/addrlen, suspending the calling fiber until the connection completes rather than blocking its worker.

Returns null on success, or the error (such as CONNECTION_REFUSED). Must run on a fiber that is on a worker.

Definition at line 349 of file io.c.

349 {
352 .fd = fd,
353 .addr = (void *)addr,
354 .addrlen = (uint32_t)addrlen,
355 };
356 return io_wait(req).maybe_error;
357}
@ SRN_REACTOR_IO_CONNECT
Connect fd to the address in addr/addrlen.
Definition reactor.h:86
Here is the call graph for this function:
Here is the caller graph for this function:

◆ srn_fiber_getsockopt()

srn_error_t * srn_fiber_getsockopt ( int fd,
int level,
int optname,
void * optval,
socklen_t * optlen )

Read a socket option into optval/optlen, like getsockopt(2).

Returns null on success, or the error.

Definition at line 486 of file io.c.

486 {
487#ifdef __linux__
488 return io_status(getsockopt(fd, level, optname, optval, optlen));
489#else
490# error "You need to patch srn_fiber_getsockopt for this platform"
491#endif
492}
Here is the call graph for this function:

◆ srn_fiber_io_retry()

bool srn_fiber_io_retry ( srn_error_t * e)

Whether a suspending IO call should be retried, true exactly when e is the transient CHANNEL_BUSY error, in which case the calling fiber yields first so its worker can consume completions (which is what reopens the channel's admission window) and run other fibers before the retry.

Any other error, and success, return false, so a do/while over this helper (see the file docs) retries precisely the backpressure case and hands every real outcome through. A retrying fiber with no runnable peers and no due completions degenerates to a paced busy loop; if that shows up in practice the upgrade is suspending on the channel until a slot frees, instead of polling.

Definition at line 261 of file io.c.

261 {
262 if (e == nullptr || e->tag != CHANNEL_BUSY) {
263 return false;
264 }
265 FIBER_TRACEPOINT(fiber_io_retry, (void *)srn_fiber_current());
267 return true;
268}
@ CHANNEL_BUSY
The channel already has a full ring's worth of operations in flight.
Definition errors.h:117
#define FIBER_TRACEPOINT(...)
Definition fiber.h:146
srn_fiber_t * srn_fiber_current(void)
The fiber currently running on this os thread, or null when the calling thread is not a worker or the...
Definition scheduler.c:1097
void srn_fiber_yield(void)
Yield cooperatively, re-enqueue the running fiber and run the next ready one.
Definition scheduler.c:1039
srn_error_tag_t tag
Definition errors.h:126
Here is the call graph for this function:

◆ srn_fiber_listen()

srn_error_t * srn_fiber_listen ( int fd,
int backlog )

Mark fd as a listening socket with the given backlog, like listen(2).

Returns null on success, or the error.

Definition at line 462 of file io.c.

462 {
463#ifdef __linux__
464 return io_status(listen(fd, backlog));
465#else
466# error "You need to patch srn_fiber_listen for this platform"
467#endif
468}
Here is the call graph for this function:

◆ srn_fiber_open()

srn_io_fd_result_t srn_fiber_open ( const char * path,
int flags,
mode_t mode )

Open path, like open(2), additionally forcing O_NONBLOCK and O_CLOEXEC so the descriptor is always safe to hand to the suspending calls above.

mode applies only when flags includes O_CREAT. The open runs synchronously on the calling thread. On success fd is the new descriptor. Regular files ignore O_NONBLOCK (they are served on the worker, not the reactor). FIFOs follow the open(2) O_NONBLOCK semantics: a read end opens at once with no writer present, and a write end with no reader fails instead of blocking until one appears.

Definition at line 503 of file io.c.

503 {
504#ifdef __linux__
505 // O_NONBLOCK keeps the reactor thread safe, a pollable descriptor (FIFO,
506 // character device) opened here must never make the reactor block in a
507 // transfer. Regular files ignore the flag and take the synchronous worker
508 // path anyway.
509 return io_fd(open(path, flags | O_NONBLOCK | O_CLOEXEC, mode));
510#else
511# error "You need to patch srn_fiber_open for this platform"
512#endif
513}
static srn_io_fd_result_t io_fd(int fd)
Definition io.c:433
Here is the call graph for this function:

◆ srn_fiber_read()

srn_io_size_result_t srn_fiber_read ( int fd,
void * buf,
size_t len,
int64_t offset )

Read up to len bytes from fd into buf, suspending the calling fiber until the operation completes rather than blocking its worker.

offset is the file offset, or -1 to read at the descriptor's current position. On success count is the number of bytes read (0 at end of file).

Definition at line 303 of file io.c.

303 {
306 .fd = fd,
307 .buf = buf,
308 .len = len,
309 .offset = offset,
310 };
311 io_waiter_t w = io_wait(req);
312 return (srn_io_size_result_t){.maybe_error = w.maybe_error, .count = w.result};
313}
@ SRN_REACTOR_IO_READ
Read from a descriptor into buf. Uses fd, buf, len, offset.
Definition reactor.h:71
The result of a byte transfer op (read/write/sendto/recvmsg/sendmsg).
Definition io.h:76
Here is the call graph for this function:
Here is the caller graph for this function:

◆ srn_fiber_recvfrom()

srn_io_recvfrom_result_t srn_fiber_recvfrom ( int fd,
void * buf,
size_t len,
int flags,
struct sockaddr * addr,
socklen_t addr_cap )

Receive a datagram from fd into buf/len with flags (the MSG_* flags), suspending the calling fiber until one arrives.

When addr is non-null the sender address is written into it, up to addr_cap bytes, and the result's addrlen reports how many. On success count is the number of bytes received. Must run on a fiber that is on a worker.

Definition at line 359 of file io.c.

361 {
364 .fd = fd,
365 .buf = buf,
366 .len = len,
367 .flags = flags,
368 .addr = addr,
369 .addrlen = (uint32_t)addr_cap,
370 };
371 io_waiter_t w = io_wait(req);
373 .maybe_error = w.maybe_error,
374 .count = w.result,
375 .addrlen = (socklen_t)w.addrlen,
376 };
377}
@ SRN_REACTOR_IO_RECVFROM
Receive a datagram from fd into buf/len with flags.
Definition reactor.h:91
The result of srn_fiber_recvfrom.
Definition io.h:97
Here is the call graph for this function:

◆ srn_fiber_recvmsg()

srn_io_size_result_t srn_fiber_recvmsg ( int fd,
struct msghdr * msg,
int flags )

Receive into the struct msghdr msg on fd with flags, suspending the calling fiber until data arrives.

Scatters across msg's iovecs and fills its msg_name/msg_control as requested. On success count is the number of bytes received. Must run on a fiber that is on a worker.

Definition at line 395 of file io.c.

395 {
398 .fd = fd,
399 .buf = msg,
400 .flags = flags,
401 };
402 io_waiter_t w = io_wait(req);
403 return (srn_io_size_result_t){.maybe_error = w.maybe_error, .count = w.result};
404}
@ SRN_REACTOR_IO_RECVMSG
Receive into the struct msghdr that buf points at, on fd, with flags (scatter/gather and ancillary da...
Definition reactor.h:99
Here is the call graph for this function:

◆ srn_fiber_sendmsg()

srn_io_size_result_t srn_fiber_sendmsg ( int fd,
const struct msghdr * msg,
int flags )

Send the struct msghdr msg on fd with flags, suspending the calling fiber until the send completes.

Gathers from msg's iovecs. On success count is the number of bytes sent. Must run on a fiber that is on a worker.

Definition at line 406 of file io.c.

406 {
409 .fd = fd,
410 .buf = (void *)msg,
411 .flags = flags,
412 };
413 io_waiter_t w = io_wait(req);
414 return (srn_io_size_result_t){.maybe_error = w.maybe_error, .count = w.result};
415}
@ SRN_REACTOR_IO_SENDMSG
Send the struct msghdr that buf points at, on fd, with flags.
Definition reactor.h:103
Here is the call graph for this function:

◆ srn_fiber_sendto()

srn_io_size_result_t srn_fiber_sendto ( int fd,
const void * buf,
size_t len,
int flags,
const struct sockaddr * addr,
socklen_t addrlen )

Send buf/len on fd to addr/addrlen with flags (the MSG_* flags), suspending the calling fiber until the send completes rather than blocking its worker.

On success count is the number of bytes sent. Must run on a fiber that is on a worker.

Definition at line 379 of file io.c.

381 {
384 .fd = fd,
385 .buf = (void *)buf,
386 .len = len,
387 .flags = flags,
388 .addr = (void *)addr,
389 .addrlen = (uint32_t)addrlen,
390 };
391 io_waiter_t w = io_wait(req);
392 return (srn_io_size_result_t){.maybe_error = w.maybe_error, .count = w.result};
393}
@ SRN_REACTOR_IO_SENDTO
Send buf/len on fd to the address in addr/addrlen with flags.
Definition reactor.h:95
Here is the call graph for this function:

◆ srn_fiber_setsockopt()

srn_error_t * srn_fiber_setsockopt ( int fd,
int level,
int optname,
const void * optval,
socklen_t optlen )

Set a socket option from optval/optlen, like setsockopt(2).

Returns null on success, or the error.

Definition at line 495 of file io.c.

495 {
496#ifdef __linux__
497 return io_status(setsockopt(fd, level, optname, optval, optlen));
498#else
499# error "You need to patch srn_fiber_setsockopt for this platform"
500#endif
501}
Here is the call graph for this function:

◆ srn_fiber_shutdown()

srn_error_t * srn_fiber_shutdown ( int fd,
int how )

Shut down part or all of the connection on fd (how is SHUT_RD/SHUT_WR/ SHUT_RDWR), like shutdown(2).

Returns null on success, or the error.

Definition at line 478 of file io.c.

478 {
479#ifdef __linux__
480 return io_status(shutdown(fd, how));
481#else
482# error "You need to patch srn_fiber_shutdown for this platform"
483#endif
484}
Here is the call graph for this function:

◆ srn_fiber_sleep()

srn_error_t * srn_fiber_sleep ( uint64_t duration)

Suspend the calling fiber for at least duration seconds, letting its worker run other fibers meanwhile.

Returns null on a normal wake, or the CANCELED error if the sleep was cut short by a scheduler wind down.

Definition at line 301 of file io.c.

301{ return srn_fiber_sleep_ns(to_ns(duration, SEC)); }
#define SEC
Definition io.c:58
srn_error_t * srn_fiber_sleep_ns(uint64_t duration_ns)
Suspend the calling fiber for at least duration_ns nanoseconds, letting its worker run other fibers m...
Definition io.c:270
static uint64_t to_ns(uint64_t duration, uint64_t ns_per_unit)
Convert a coarser duration to nanoseconds, saturating instead of wrapping.
Definition io.c:289
Here is the call graph for this function:
Here is the caller graph for this function:

◆ srn_fiber_sleep_ms()

srn_error_t * srn_fiber_sleep_ms ( uint64_t duration_ms)

Suspend the calling fiber for at least duration_ms miliseconds, letting its worker run other fibers meanwhile.

Returns null on a normal wake, or the CANCELED error if the sleep was cut short by a scheduler wind down.

Definition at line 297 of file io.c.

297 {
298 return srn_fiber_sleep_ns(to_ns(duration_ms, MILLISEC));
299}
#define MILLISEC
Definition io.c:57
Here is the call graph for this function:
Here is the caller graph for this function:

◆ srn_fiber_sleep_ns()

srn_error_t * srn_fiber_sleep_ns ( uint64_t duration_ns)

Suspend the calling fiber for at least duration_ns nanoseconds, letting its worker run other fibers meanwhile.

Returns null on a normal wake, or the CANCELED error if the sleep was cut short by a scheduler wind down.

Definition at line 270 of file io.c.

270 {
271 uint64_t now = srn_now_ns();
272
273 // Saturate instead of wrapping, an absurd duration means "sleep past any
274 // horizon", not "wake at once".
275 uint64_t deadline = duration_ns > UINT64_MAX - now ? UINT64_MAX : now + duration_ns;
276
279 .deadline_ns = deadline,
280 };
281 return io_wait(req).maybe_error;
282}
@ SRN_REACTOR_IO_SLEEP
Wait out a deadline.
Definition reactor.h:69
uint64_t srn_now_ns(void)
The current time on the monotonic clock, in nanoseconds.
Definition utils.c:46
Here is the call graph for this function:
Here is the caller graph for this function:

◆ srn_fiber_sleep_us()

srn_error_t * srn_fiber_sleep_us ( uint64_t duration_us)

Suspend the calling fiber for at least duration_us microseconds, letting its worker run other fibers meanwhile.

Returns null on a normal wake, or the CANCELED error if the sleep was cut short by a scheduler wind down.

Definition at line 293 of file io.c.

293 {
294 return srn_fiber_sleep_ns(to_ns(duration_us, MICROSEC));
295}
#define MICROSEC
Definition io.c:56
Here is the call graph for this function:

◆ srn_fiber_socket()

srn_io_fd_result_t srn_fiber_socket ( int domain,
int type,
int protocol )

Create a socket, like socket(2), additionally forcing SOCK_NONBLOCK and SOCK_CLOEXEC so the descriptor is safe to hand to the suspending calls (a blocking socket would stall the reactor thread).

On success fd is the new descriptor.

Definition at line 446 of file io.c.

446 {
447#ifdef __linux__
448 return io_fd(socket(domain, type | SOCK_NONBLOCK | SOCK_CLOEXEC, protocol));
449#else
450# error "You need to patch srn_fiber_socket for this platform"
451#endif
452}
Here is the call graph for this function:

◆ srn_fiber_write()

srn_io_size_result_t srn_fiber_write ( int fd,
const void * buf,
size_t len,
int64_t offset )

Write len bytes from buf to fd, suspending the calling fiber until the operation completes rather than blocking its worker.

offset is the file offset, or -1 to write at the descriptor's current position. On success count is the number of bytes written.

Definition at line 315 of file io.c.

315 {
318 .fd = fd,
319 .buf = (void *)buf,
320 .len = len,
321 .offset = offset,
322 };
323 io_waiter_t w = io_wait(req);
324 return (srn_io_size_result_t){.maybe_error = w.maybe_error, .count = w.result};
325}
@ SRN_REACTOR_IO_WRITE
Write buf to a descriptor. Uses fd, buf, len, offset.
Definition reactor.h:73
Here is the call graph for this function:
Here is the caller graph for this function: