TreeFrogFramework 2.10
Loading...
Searching...
No Matches
tfcore_unix.h
Go to the documentation of this file.
1#pragma once
2#include "tfcore.h"
3#include <fcntl.h>
4#include <poll.h>
5#include <sys/file.h>
6#include <sys/socket.h>
7#include <sys/syscall.h>
8#include <sys/types.h>
9#include <sys/wait.h>
10#include <netinet/in.h>
11#include <unistd.h>
12#include <thread>
13#include <cstdint>
14
15#ifdef Q_OS_LINUX
16#include <sys/epoll.h>
17#endif
18#ifdef Q_OS_DARWIN
19#include <pthread.h>
20#endif
21#ifdef Q_OS_WASM
22#include <sstream>
23#endif
24
25#ifndef Q_OS_UNIX
26#error "tfcore_unix.h included on a non-Unix system"
27#endif
28
29namespace {
30
31#ifdef Q_OS_LINUX
32
33inline int tf_ppoll(struct pollfd *fds, nfds_t nfds, const struct timespec *ts)
34{
35 TF_EAGAIN_LOOP(::ppoll(fds, nfds, ts, nullptr));
36}
37
38
39inline int tf_poll(struct pollfd *fds, nfds_t nfds, int timeout)
40{
41 struct timespec ts = {timeout / 1000, (timeout % 1000) * 1000000L};
42 return tf_ppoll(fds, nfds, &ts);
43}
44
45
46inline int tf_epoll_wait(int epfd, struct epoll_event *events,
47 int maxevents, int timeout)
48{
49 TF_EINTR_LOOP(::epoll_wait(epfd, events, maxevents, timeout));
50}
51
52
53inline int tf_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
54{
55 TF_EINTR_LOOP(::epoll_ctl(epfd, op, fd, event));
56}
57
58
59inline int tf_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags)
60{
61 TF_EINTR_LOOP(::accept4(sockfd, addr, addrlen, flags));
62}
63
64
65inline int tf_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
66{
67 TF_EINTR_LOOP(::connect(sockfd, addr, addrlen));
68}
69
70
71inline pid_t tf_gettid()
72{
73 return syscall(SYS_gettid);
74}
75
76
77inline int tf_send(int sockfd, const void *buf, size_t len, int flags = 0)
78{
79 flags |= MSG_NOSIGNAL;
80 TF_EINTR_LOOP(::send(sockfd, buf, len, flags));
81}
82
83#endif // Q_OS_LINUX
84
85#ifdef Q_OS_DARWIN
86
87inline int tf_poll(struct pollfd *fds, nfds_t nfds, int timeout)
88{
89 TF_EAGAIN_LOOP(::poll(fds, nfds, timeout));
90}
91
92
93inline pid_t tf_gettid()
94{
95 uint64_t tid;
96 pthread_threadid_np(NULL, &tid);
97 return tid;
98}
99
100
101inline int tf_send(int sockfd, const void *buf, size_t len, int flags = 0)
102{
103 TF_EINTR_LOOP(::send(sockfd, buf, len, flags));
104}
105
106#endif // Q_OS_DARWIN
107
108#ifdef Q_OS_WASM
109
110inline int tf_poll(struct pollfd *fds, nfds_t nfds, int timeout)
111{
112 TF_EAGAIN_LOOP(::poll(fds, nfds, timeout));
113}
114
115
116inline pid_t tf_gettid()
117{
118 std::ostringstream ss;
119 ss << std::this_thread::get_id();
120 return std::stoull(ss.str());
121}
122
123
124inline int tf_send(int sockfd, const void *buf, size_t len, int flags = 0)
125{
126 TF_EINTR_LOOP(::send(sockfd, buf, len, flags));
127}
128
129#endif // Q_OS_WASM
130
131// inline int tf_aio_write(struct aiocb *aiocbp)
132// {
133// TF_EINTR_LOOP(::aio_write(aiocbp));
134// }
135
136
137inline int tf_close(int fd)
138{
139 TF_EINTR_LOOP(::close(fd));
140}
141
142
143inline int tf_read(int fd, void *buf, size_t count)
144{
145 TF_EINTR_LOOP(::read(fd, buf, count));
146}
147
148
149inline int tf_write(int fd, const void *buf, size_t count)
150{
151 TF_EINTR_LOOP(::write(fd, buf, count));
152}
153
154
155inline int tf_recv(int sockfd, void *buf, size_t len, int flags = 0)
156{
157 TF_EINTR_LOOP(::recv(sockfd, buf, len, flags));
158}
159
160
161inline int tf_close_socket(int sockfd)
162{
163 TF_EINTR_LOOP(::close(sockfd));
164}
165
166
167inline int tf_dup(int fd)
168{
169 return ::fcntl(fd, F_DUPFD, 0);
170}
171
172
173inline int tf_flock(int fd, int op)
174{
175 TF_EINTR_LOOP(::flock(fd, op));
176}
177
178// advisory lock. exclusive:true=exclusive lock, false=shared lock
179inline int tf_lockfile(int fd, bool exclusive, bool blocking)
180{
181 struct flock lck;
182
183 std::memset(&lck, 0, sizeof(struct flock));
184 lck.l_type = (exclusive) ? F_WRLCK : F_RDLCK;
185 lck.l_whence = SEEK_SET;
186 auto cmd = (blocking) ? F_SETLKW : F_SETLK;
187 TF_EINTR_LOOP(::fcntl(fd, cmd, &lck));
188}
189
190
191inline int tf_unlink(const char *pathname)
192{
193 return ::unlink(pathname);
194}
195
196
197inline int tf_fileno(FILE *stream)
198{
199 return ::fileno(stream);
200}
201
206inline int tf_poll_recv(int socket, int timeout)
207{
208 struct pollfd pfd = {socket, POLLIN, 0};
209 int ret = tf_poll(&pfd, 1, timeout);
210 return ret;
211}
212
217inline int tf_poll_send(int socket, int timeout)
218{
219 struct pollfd pfd = {socket, POLLOUT, 0};
220 int ret = tf_poll(&pfd, 1, timeout);
221 return ret;
222}
223
224} // namespace
#define TF_EAGAIN_LOOP(func)
Definition tfcore.h:20
#define TF_EINTR_LOOP(func)
Definition tfcore.h:12