Zth (libzth)
io.cpp
Go to the documentation of this file.
1 /*
2  * Zth (libzth), a cooperative userspace multitasking library.
3  * Copyright (C) 2019-2022 Jochem Rutgers
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
8  */
9 
10 #include <libzth/config.h>
11 #include <libzth/io.h>
12 #include <libzth/poller.h>
13 #include <libzth/util.h>
14 #include <libzth/worker.h>
15 #include <libzth/zmq.h>
16 
17 #if defined(ZTH_HAVE_POLLER) && !defined(ZTH_OS_WINDOWS)
18 # include <fcntl.h>
19 
20 namespace zth {
21 namespace io {
22 
27 ssize_t read(int fd, void* buf, size_t count)
28 {
29  perf_syscall("read()");
30 
31  int flags = fcntl(fd, F_GETFL);
32  if(unlikely(flags == -1))
33  return -1; // with errno set
34 
35  // NOLINTNEXTLINE(hicpp-signed-bitwise)
36  if((flags & O_NONBLOCK)) {
37  zth_dbg(io, "[%s] read(%d) non-blocking", currentFiber().str().c_str(), fd);
38  // Just do the call.
39  return ::read(fd, buf, count);
40  }
41 
42  if((errno = zth::poll(PollableFd(fd, Pollable::PollIn), -1)))
43  return -1;
44 
45  // Got data to read.
46  zth_dbg(io, "[%s] read(%d)", currentFiber().str().c_str(), fd);
47  return ::read(fd, buf, count);
48 }
49 
54 ssize_t write(int fd, void const* buf, size_t count)
55 {
56  perf_syscall("write()");
57 
58  int flags = fcntl(fd, F_GETFL);
59  if(unlikely(flags == -1))
60  return -1; // with errno set
61 
62  // NOLINTNEXTLINE(hicpp-signed-bitwise)
63  if((flags & O_NONBLOCK)) {
64  zth_dbg(io, "[%s] write(%d) non-blocking", currentFiber().str().c_str(), fd);
65  // Just do the call.
66  return ::write(fd, buf, count);
67  }
68 
69  if((errno = zth::poll(PollableFd(fd, Pollable::PollOut), -1)))
70  return -1;
71 
72  // Go write the data.
73  zth_dbg(io, "[%s] write(%d)", currentFiber().str().c_str(), fd);
74  return ::write(fd, buf, count);
75 }
76 
77 } // namespace io
78 } // namespace zth
79 #else
80 static int no_io __attribute__((unused));
81 #endif // ZTH_HAVE_POLLER
Fiber & currentFiber() noexcept
Return the currently executing fiber.
Definition: worker.h:398
ssize_t read(int fd, void *buf, size_t count)
Like normal read(), but forwards the poll() to the zth::Waiter in case it would block.
Definition: io.cpp:27
ssize_t write(int fd, void const *buf, size_t count)
Like normal write(), but forwards the poll() to the zth::Waiter in case it would block.
Definition: io.cpp:54
int poll(P pollable, int timeout_ms=-1)
Fiber-aware poll() for a single pollable thing.
Definition: poller.h:783
#define zth_dbg(group, fmt, a...)
Debug printf()-like function.
Definition: util.h:210
Definition: allocator.h:23
cow_string str(T value)
Returns an zth::string representation of the given value.
Definition: util.h:517
void perf_syscall(char const *syscall, Timestamp const &t=Timestamp())
Put a syscall into the perf output.
Definition: perf.h:359
A pollable file descriptor.
Definition: poller.h:138
static const unsigned long PollIn
Definition: poller.h:92
static const unsigned long PollOut
Definition: poller.h:93
#define unlikely(expr)
Marks the given expression to likely be evaluated to true.
Definition: util.h:56