VLC  4.0.0-dev
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
vlc_interrupt.h
Go to the documentation of this file.
1 /*****************************************************************************
2  * vlc_interrupt.h:
3  *****************************************************************************
4  * Copyright (C) 2015 Remlab T:mi
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation; either version 2.1 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19  *****************************************************************************/
20 
21 #ifndef VLC_INTERRUPT_H
22 # define VLC_INTERRUPT_H 1
23 # include <vlc_threads.h>
24 # ifndef _WIN32
25 # include <sys/socket.h> /* socklen_t */
26 # else
27 # include <ws2tcpip.h>
28 # endif
29 
30 struct pollfd;
31 struct iovec;
32 struct sockaddr;
33 struct msghdr;
34 
35 /**
36  * @defgroup interrupt Interruptible sleep
37  * @ingroup thread
38  * @{
39  * @file
40  * This file declares interruptible sleep functions.
41  * @defgroup interrupt_sleep Interruptible sleep functions
42  * @{
43  */
44 
45 /**
46  * Interruptible variant of vlc_sem_wait().
47  *
48  * Waits on a semaphore like vlc_sem_wait(). If the calling thread has an
49  * interruption context (as set by vlc_interrupt_set()), and another thread
50  * invokes vlc_interrupt_raise() on that context, the semaphore is incremented.
51  *
52  * @warning The calling thread should be the only thread ever to wait on the
53  * specified semaphore. Otherwise, interruptions may not be delivered
54  * accurately (the wrong thread may be woken up).
55  *
56  * @note This function is (always) a cancellation point.
57  *
58  * @return EINTR if the semaphore was incremented due to an interruption,
59  * otherwise zero.
60  */
62 
63 /**
64  * Interruptible variant of vlc_tick_wait().
65  *
66  * Waits for a specified timestamp or, if the calling thread has an
67  * interruption context, an interruption.
68  *
69  * @return EINTR if an interruption occurred, otherwise 0 once the timestamp is
70  * reached.
71  */
73 
74 /**
75  * Interruptible variant of vlc_tick_sleep().
76  *
77  * Waits for a specified timeout duration or, if the calling thread has an
78  * interruption context, an interruption.
79  *
80  * @param delay timeout value (in microseconds)
81  *
82  * @return EINTR if an interruption occurred, otherwise 0 once the timeout
83  * expired.
84  */
85 static inline int vlc_msleep_i11e(vlc_tick_t delay)
86 {
87  return vlc_mwait_i11e(vlc_tick_now() + delay);
88 }
89 
90 /**
91  * Interruptible variant of poll().
92  *
93  * Waits for file descriptors I/O events, a timeout, a signal or a VLC I/O
94  * interruption. Except for VLC I/O interruptions, this function behaves
95  * just like the standard poll().
96  *
97  * @note This function is always a cancellation point (as poll()).
98  * @see poll() manual page
99  *
100  * @param fds table of events to wait for
101  * @param nfds number of entries in the table
102  * @param timeout time to wait in milliseconds or -1 for infinite
103  *
104  * @return A strictly positive result represent the number of pending events.
105  * 0 is returned if the time-out is reached without events.
106  * -1 is returned if a VLC I/O interrupt occurs (and errno is set to EINTR)
107  * or if an error occurs.
108  */
109 VLC_API int vlc_poll_i11e(struct pollfd *, unsigned, int);
110 
111 VLC_API ssize_t vlc_readv_i11e(int fd, struct iovec *, int);
112 VLC_API ssize_t vlc_writev_i11e(int fd, const struct iovec *, int);
113 VLC_API ssize_t vlc_read_i11e(int fd, void *, size_t);
114 VLC_API ssize_t vlc_write_i11e(int fd, const void *, size_t);
115 
116 VLC_API ssize_t vlc_recvmsg_i11e(int fd, struct msghdr *, int flags);
117 VLC_API ssize_t vlc_sendmsg_i11e(int fd, const struct msghdr *, int flags);
118 
119 VLC_API ssize_t vlc_recvfrom_i11e(int fd, void *, size_t, int flags,
120  struct sockaddr *, socklen_t *);
121 VLC_API ssize_t vlc_sendto_i11e(int fd, const void *, size_t, int flags,
122  const struct sockaddr *, socklen_t);
123 
124 static inline ssize_t vlc_recv_i11e(int fd, void *buf, size_t len, int flags)
125 {
126  return vlc_recvfrom_i11e(fd, buf, len, flags, NULL, NULL);
127 }
128 
129 static inline
130 ssize_t vlc_send_i11e(int fd, const void *buf, size_t len, int flags)
131 {
132  return vlc_sendto_i11e(fd, buf, len, flags, NULL, 0);
133 }
134 
135 VLC_API int vlc_accept_i11e(int fd, struct sockaddr *, socklen_t *, bool);
136 
137 /**
138  * Registers a custom interrupt handler.
139  *
140  * Registers a custom callback as interrupt handler for the calling thread.
141  * The callback must be unregistered with vlc_interrupt_unregister() before
142  * thread termination and before any further callback registration.
143  *
144  * If the calling thread has no interruption context, this function has no
145  * effects.
146  */
147 VLC_API void vlc_interrupt_register(void (*cb)(void *), void *opaque);
148 
150 
151 /**
152  * @}
153  * @defgroup interrupt_context Interrupt context signaling and manipulation
154  * @{
155  */
156 typedef struct vlc_interrupt vlc_interrupt_t;
158 /**
159  * Creates an interruption context.
160  */
161 VLC_API vlc_interrupt_t *vlc_interrupt_create(void) VLC_USED;
162 
163 /**
164  * Destroys an interrupt context.
165  */
166 VLC_API void vlc_interrupt_destroy(vlc_interrupt_t *);
167 
168 /**
169  * Sets the interruption context for the calling thread.
170  * @param newctx the interruption context to attach or NULL for none
171  * @return the previous interruption context or NULL if none
172  *
173  * @note This function is not a cancellation point.
174  * @warning A context can be attached to no more than one thread at a time.
175  */
176 VLC_API vlc_interrupt_t *vlc_interrupt_set(vlc_interrupt_t *);
177 
178 /**
179  * Raises an interruption through a specified context.
180  *
181  * This is used to asynchronously wake a thread up while it is waiting on some
182  * other events (typically I/O events).
183  *
184  * @note This function is thread-safe.
185  * @note This function is not a cancellation point.
186  */
187 VLC_API void vlc_interrupt_raise(vlc_interrupt_t *);
188 
189 /**
190  * Marks the interruption context as "killed".
191  *
192  * This is not reversible.
193  */
194 VLC_API void vlc_interrupt_kill(vlc_interrupt_t *);
195 
196 /**
197  * Checks if the interruption context was "killed".
198  *
199  * Indicates whether the interruption context of the calling thread (if any)
200  * was killed with vlc_interrupt_kill().
201  */
202 VLC_API bool vlc_killed(void) VLC_USED;
203 
204 /**
205  * Enables forwarding of interruption.
206  *
207  * If an interruption is raised through the context of the calling thread,
208  * it will be forwarded to the specified other context. This is used to cross
209  * thread boundaries.
210  *
211  * If the calling thread has no interrupt context, this function does nothing.
212  *
213  * @param to context to forward to
214  */
215 VLC_API void vlc_interrupt_forward_start(vlc_interrupt_t *to,
216  void *data[2]);
217 
218 /**
219  * Undoes vlc_interrupt_forward_start().
220  *
221  * This function must be called after each successful call to
222  * vlc_interrupt_forward_start() before any other interruptible call is made
223  * in the same thread.
224  *
225  * If an interruption was raised against the context of the calling thread
226  * (after the previous call to vlc_interrupt_forward_start()), it is dequeued.
227  *
228  * If the calling thread has no interrupt context, this function does nothing
229  * and returns zero.
230  *
231  * @return 0 if no interrupt was raised, EINTR if an interrupt was raised
232  */
233 VLC_API int vlc_interrupt_forward_stop(void *const data[2]);
234 
235 /** @} @} */
236 #endif
Semaphore.
Definition: vlc_threads.h:498
static ssize_t vlc_send_i11e(int fd, const void *buf, size_t len, int flags)
Definition: vlc_interrupt.h:131
void vlc_interrupt_register(void(*cb)(void *), void *opaque)
Registers a custom interrupt handler.
Definition: interrupt.c:159
int vlc_mwait_i11e(vlc_tick_t)
Interruptible variant of vlc_tick_wait().
Definition: interrupt.c:225
bool vlc_killed(void)
Checks if the interruption context was "killed".
Definition: interrupt.c:185
void vlc_interrupt_destroy(vlc_interrupt_t *)
Destroys an interrupt context.
Definition: interrupt.c:76
void * data
Definition: interrupt.h:38
vlc_tick_t vlc_tick_now(void)
Precision monotonic clock.
Definition: thread.c:292
int vlc_interrupt_forward_stop(void *const data[2])
Undoes vlc_interrupt_forward_start().
Definition: interrupt.c:270
ssize_t vlc_recvfrom_i11e(int fd, void *, size_t, int flags, struct sockaddr *, socklen_t *)
Definition: interrupt.c:482
ssize_t vlc_write_i11e(int fd, const void *, size_t)
Wrapper for write() that returns the EINTR error upon VLC I/O interruption.
Definition: interrupt.c:462
ssize_t vlc_writev_i11e(int fd, const struct iovec *, int)
Wrapper for writev() that returns the EINTR error upon VLC I/O interruption.
Definition: interrupt.c:433
int64_t vlc_tick_t
High precision date or time interval.
Definition: vlc_tick.h:45
static ssize_t vlc_recv_i11e(int fd, void *buf, size_t len, int flags)
Definition: vlc_interrupt.h:125
ssize_t vlc_readv_i11e(int fd, struct iovec *, int)
Wrapper for readv() that returns the EINTR error upon VLC I/O interruption.
Definition: interrupt.c:414
void vlc_interrupt_forward_start(vlc_interrupt_t *to, void *data[2])
Enables forwarding of interruption.
Definition: interrupt.c:256
int vlc_interrupt_unregister(void)
Definition: interrupt.c:166
vlc_interrupt_t * vlc_interrupt_set(vlc_interrupt_t *)
Sets the interruption context for the calling thread.
Definition: interrupt.c:98
void vlc_interrupt_raise(vlc_interrupt_t *)
Raises an interruption through a specified context.
Definition: interrupt.c:83
Definition: vlc_fixups.h:409
ssize_t vlc_recvmsg_i11e(int fd, struct msghdr *, int flags)
Definition: interrupt.c:468
#define VLC_API
Definition: fourcc_gen.c:31
Definition: interrupt.h:32
vlc_interrupt_t * vlc_interrupt_create(void)
Creates an interruption context.
Definition: interrupt.c:59
int vlc_sem_wait_i11e(vlc_sem_t *)
Interruptible variant of vlc_sem_wait().
Definition: interrupt.c:197
static int vlc_msleep_i11e(vlc_tick_t delay)
Interruptible variant of vlc_tick_sleep().
Definition: vlc_interrupt.h:86
Thread primitive declarations.
ssize_t vlc_read_i11e(int fd, void *, size_t)
Wrapper for read() that returns the EINTR error upon VLC I/O interruption.
Definition: interrupt.c:449
int vlc_accept_i11e(int fd, struct sockaddr *, socklen_t *, bool)
Definition: interrupt.c:526
ssize_t vlc_sendmsg_i11e(int fd, const struct msghdr *, int flags)
Definition: interrupt.c:499
void vlc_interrupt_kill(vlc_interrupt_t *)
Marks the interruption context as "killed".
Definition: interrupt.c:177
ssize_t vlc_sendto_i11e(int fd, const void *, size_t, int flags, const struct sockaddr *, socklen_t)
Definition: interrupt.c:512
#define VLC_USED
Definition: fourcc_gen.c:32
int vlc_poll_i11e(struct pollfd *, unsigned, int)
Interruptible variant of poll().
Definition: interrupt.c:367