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:243

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 308 of file io.c.

308 {
309#ifdef __linux__
310 // Force the accepted socket non-blocking and close-on-exec, so further fiber
311 // IO on it never blocks the reactor thread and it does not leak across exec.
314 .fd = fd,
315 .addr = addr,
316 .addrlen = (uint32_t)addr_cap,
317 .flags = SOCK_NONBLOCK | SOCK_CLOEXEC,
318 };
319 io_waiter_t w = io_wait(req);
320 return (srn_io_accept_result_t){
321 .maybe_error = w.maybe_error,
322 .fd = (int)w.result,
323 .addrlen = (socklen_t)w.addrlen,
324 };
325#else
326# error "You need to patch srn_fiber_accept for this platform"
327#endif
328}
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:206
@ SRN_REACTOR_IO_ACCEPT
Accept a pending connection on the listening socket fd, with flags (the accept4 flags).
Definition reactor.h:79
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:113
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 435 of file io.c.

435 {
436#ifdef __linux__
437 return io_status(bind(fd, addr, addrlen));
438#else
439# error "You need to patch srn_fiber_bind for this platform"
440#endif
441}
static srn_error_t * io_status(int rc)
Definition io.c:405
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 451 of file io.c.

451 {
452#ifdef __linux__
453 return io_status(close(fd));
454#else
455# error "You need to patch srn_fiber_close for this platform"
456#endif
457}
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 330 of file io.c.

330 {
333 .fd = fd,
334 .addr = (void *)addr,
335 .addrlen = (uint32_t)addrlen,
336 };
337 return io_wait(req).maybe_error;
338}
@ SRN_REACTOR_IO_CONNECT
Connect fd to the address in addr/addrlen.
Definition reactor.h:83
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 467 of file io.c.

467 {
468#ifdef __linux__
469 return io_status(getsockopt(fd, level, optname, optval, optlen));
470#else
471# error "You need to patch srn_fiber_getsockopt for this platform"
472#endif
473}
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 243 of file io.c.

243 {
244 if (e == nullptr || e->tag != CHANNEL_BUSY) {
245 return false;
246 }
248 return true;
249}
@ CHANNEL_BUSY
The channel already has a full ring's worth of operations in flight.
Definition errors.h:117
void srn_fiber_yield(void)
Yield cooperatively, re-enqueue the running fiber and run the next ready one.
Definition scheduler.c:1000
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 443 of file io.c.

443 {
444#ifdef __linux__
445 return io_status(listen(fd, backlog));
446#else
447# error "You need to patch srn_fiber_listen for this platform"
448#endif
449}
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 484 of file io.c.

484 {
485#ifdef __linux__
486 // O_NONBLOCK keeps the reactor thread safe, a pollable descriptor (FIFO,
487 // character device) opened here must never make the reactor block in a
488 // transfer. Regular files ignore the flag and take the synchronous worker
489 // path anyway.
490 return io_fd(open(path, flags | O_NONBLOCK | O_CLOEXEC, mode));
491#else
492# error "You need to patch srn_fiber_open for this platform"
493#endif
494}
static srn_io_fd_result_t io_fd(int fd)
Definition io.c:414
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 284 of file io.c.

284 {
287 .fd = fd,
288 .buf = buf,
289 .len = len,
290 .offset = offset,
291 };
292 io_waiter_t w = io_wait(req);
293 return (srn_io_size_result_t){.maybe_error = w.maybe_error, .count = w.result};
294}
@ SRN_REACTOR_IO_READ
Read from a descriptor into buf. Uses fd, buf, len, offset.
Definition reactor.h:68
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 340 of file io.c.

342 {
345 .fd = fd,
346 .buf = buf,
347 .len = len,
348 .flags = flags,
349 .addr = addr,
350 .addrlen = (uint32_t)addr_cap,
351 };
352 io_waiter_t w = io_wait(req);
354 .maybe_error = w.maybe_error,
355 .count = w.result,
356 .addrlen = (socklen_t)w.addrlen,
357 };
358}
@ SRN_REACTOR_IO_RECVFROM
Receive a datagram from fd into buf/len with flags.
Definition reactor.h:88
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 376 of file io.c.

376 {
379 .fd = fd,
380 .buf = msg,
381 .flags = flags,
382 };
383 io_waiter_t w = io_wait(req);
384 return (srn_io_size_result_t){.maybe_error = w.maybe_error, .count = w.result};
385}
@ 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:96
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 387 of file io.c.

387 {
390 .fd = fd,
391 .buf = (void *)msg,
392 .flags = flags,
393 };
394 io_waiter_t w = io_wait(req);
395 return (srn_io_size_result_t){.maybe_error = w.maybe_error, .count = w.result};
396}
@ SRN_REACTOR_IO_SENDMSG
Send the struct msghdr that buf points at, on fd, with flags.
Definition reactor.h:100
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 360 of file io.c.

362 {
365 .fd = fd,
366 .buf = (void *)buf,
367 .len = len,
368 .flags = flags,
369 .addr = (void *)addr,
370 .addrlen = (uint32_t)addrlen,
371 };
372 io_waiter_t w = io_wait(req);
373 return (srn_io_size_result_t){.maybe_error = w.maybe_error, .count = w.result};
374}
@ SRN_REACTOR_IO_SENDTO
Send buf/len on fd to the address in addr/addrlen with flags.
Definition reactor.h:92
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 476 of file io.c.

476 {
477#ifdef __linux__
478 return io_status(setsockopt(fd, level, optname, optval, optlen));
479#else
480# error "You need to patch srn_fiber_setsockopt for this platform"
481#endif
482}
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 459 of file io.c.

459 {
460#ifdef __linux__
461 return io_status(shutdown(fd, how));
462#else
463# error "You need to patch srn_fiber_shutdown for this platform"
464#endif
465}
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 282 of file io.c.

282{ 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:251
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:270
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 278 of file io.c.

278 {
279 return srn_fiber_sleep_ns(to_ns(duration_ms, MILLISEC));
280}
#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 251 of file io.c.

251 {
252 uint64_t now = srn_now_ns();
253
254 // Saturate instead of wrapping, an absurd duration means "sleep past any
255 // horizon", not "wake at once".
256 uint64_t deadline = duration_ns > UINT64_MAX - now ? UINT64_MAX : now + duration_ns;
257
260 .deadline_ns = deadline,
261 };
262 return io_wait(req).maybe_error;
263}
@ SRN_REACTOR_IO_SLEEP
Wait out a deadline.
Definition reactor.h:66
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 274 of file io.c.

274 {
275 return srn_fiber_sleep_ns(to_ns(duration_us, MICROSEC));
276}
#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 427 of file io.c.

427 {
428#ifdef __linux__
429 return io_fd(socket(domain, type | SOCK_NONBLOCK | SOCK_CLOEXEC, protocol));
430#else
431# error "You need to patch srn_fiber_socket for this platform"
432#endif
433}
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 296 of file io.c.

296 {
299 .fd = fd,
300 .buf = (void *)buf,
301 .len = len,
302 .offset = offset,
303 };
304 io_waiter_t w = io_wait(req);
305 return (srn_io_size_result_t){.maybe_error = w.maybe_error, .count = w.result};
306}
@ SRN_REACTOR_IO_WRITE
Write buf to a descriptor. Uses fd, buf, len, offset.
Definition reactor.h:70
Here is the call graph for this function:
Here is the caller graph for this function: