1 /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3  *     Copyright 2017 Couchbase, Inc.
4  *
5  *   Licensed under the Apache License, Version 2.0 (the "License");
6  *   you may not use this file except in compliance with the License.
7  *   You may obtain a copy of the License at
8  *
9  *       http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *   Unless required by applicable law or agreed to in writing, software
12  *   distributed under the License is distributed on an "AS IS" BASIS,
13  *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *   See the License for the specific language governing permissions and
15  *   limitations under the License.
16  */
17 
18 #ifndef LIBCOUCHBASE_COUCHBASE_H
19 #error "include libcouchbase/couchbase.h first"
20 #endif
21 
22 #ifndef LCB_IOPS_H
23 #define LCB_IOPS_H
24 
25 /**
26  * @file
27  * @brief Public I/O integration interface
28  * @details
29  *
30  * This file provides the public I/O interface for integrating with external
31  * event loops.
32  */
33 
34 /**
35  * @ingroup lcbio lcb-public-api
36  * @defgroup lcb-io-plugin-api Network I/O
37  * @details
38  *
39  * I/O Integration comes in two flavors:
40  *
41  * @par (E)vent/Poll Based Integration
42  * This system is based upon the interfaces exposed by the `poll(2)` and
43  * `select(2)` calls found in POSIX-based systems and are wrapped by systems
44  * such as _libevent_ and _libev_. At their core is the notion that a socket
45  * may be polled for readiness (either readiness for reading or readiness
46  * for writing). When a socket is deemed ready, a callback is invoked indicating
47  * which events took place.
48  *
49  *
50  * @par (C)ompletion/Operation/Buffer Based Integration
51  * This system is based upon the interfaces exposed in the Win32 API where
52  * I/O is done in terms of operations which are awaiting _completion_. As such
53  * buffers are passed into the core, and the application is notified when the
54  * operation on those buffers (either read into a buffer, or write from a buffer)
55  * has been completed.
56  *
57  *
58  * @addtogroup lcb-io-plugin-api
59  * @{
60  */
61 
62 #ifdef __cplusplus
63 extern "C" {
64 #endif
65 
66 /** @brief Type representing the native socket type of the operating system */
67 #ifdef _WIN32
68 typedef SOCKET lcb_socket_t;
69 #else
70 typedef int lcb_socket_t;
71 #endif
72 
73 struct sockaddr;
74 
75 #ifndef _WIN32
76 /** Defined if the lcb_IOV structure conforms to `struct iovec` */
77 #define LCB_IOV_LAYOUT_UIO
78 typedef struct lcb_iovec_st {
79     void *iov_base;
80     size_t iov_len;
81 } lcb_IOV;
82 #else
83 /** Defined if the lcb_IOV structure conforms to `WSABUF` */
84 #define LCB_IOV_LAYOUT_WSABUF
85 typedef struct lcb_iovec_st {
86     ULONG iov_len;
87     void *iov_base;
88 } lcb_IOV;
89 #endif
90 
91 #if defined(LIBCOUCHBASE_INTERNAL) && !defined(LCB_IOPS_V12_NO_DEPRECATE)
92 #define LCB__IOPS_CONCAT2(X, Y) X ## Y
93 #define LCB__IOPS_CONCAT(X, Y) LCB__IOPS_CONCAT2(X, Y)
94 #define LCB_IOPS_DEPRECATED(X) void (*LCB__IOPS_CONCAT(lcb__iops__dummy, __LINE__))(void)
95 #else
96 #define LCB_IOPS_DEPRECATED(X) X
97 #endif
98 
99 /** @brief structure describing a connected socket's endpoints */
100 struct lcb_nameinfo_st {
101     struct {
102         struct sockaddr *name;
103         int *len;
104     } local;
105 
106     struct {
107         struct sockaddr *name;
108         int *len;
109     } remote;
110 };
111 
112 /**
113  * @struct lcb_IOV
114  * @brief structure indicating a buffer and its size
115  *
116  * @details
117  * This is compatible with a `struct iovec` on Unix and a `WSABUF` structure
118  * on Windows. It has an `iov_base` field which is the base pointer and an
119  * `iov_len` field which is the length of the buffer.
120  */
121 
122 typedef struct lcb_io_opt_st* lcb_io_opt_t;
123 
124 /**
125  * @brief Callback invoked for all poll-like events
126  *
127  * @param sock the socket associated with the event
128  * @param events the events which activated this callback. This is set of bits
129  *        comprising of LCB_READ_EVENT, LCB_WRITE_EVENT, and LCB_ERROR_EVENT
130  * @param uarg a user-defined pointer passed to the
131  *        lcb_ioE_event_watch_fn routine.
132  */
133 typedef void (*lcb_ioE_callback)
134         (lcb_socket_t sock, short events, void *uarg);
135 
136 /**@name Timer Callbacks
137  *@{*/
138 
139 /**
140  * @brief Create a new timer object.
141  *
142  * @param iops the io structure
143  * @return an opaque timer handle. The timer shall remain inactive and shall
144  *         be destroyed via the lcb_io_timer_destroy_fn routine.
145  */
146 typedef void *(*lcb_io_timer_create_fn)
147         (lcb_io_opt_t iops);
148 
149 /**
150  * @brief Destroy a timer handler
151  *
152  * Destroy a timer previously created with lcb_io_timer_create_fn
153  * @param iops the io structure
154  * @param timer the opaque handle
155  * The timer must have already been cancelled via lcb_io_timer_cancel_fn
156  */
157 typedef void (*lcb_io_timer_destroy_fn)
158         (lcb_io_opt_t iops, void *timer);
159 
160 /**
161  * @brief Cancel a pending timer callback
162  *
163  * Cancel and unregister a pending timer. If the timer has already
164  * fired, this does nothing. If the timer has not yet fired, the callback
165  * shall not be delivered.
166  *
167  * @param iops the I/O structure
168  * @param timer the timer to cancel.
169  */
170 typedef void (*lcb_io_timer_cancel_fn)
171         (lcb_io_opt_t iops, void *timer);
172 
173 /**
174  * @brief Schedule a callback to be invoked within a given interval.
175  *
176  * Schedule a timer to be fired within usec microseconds from now
177  * @param iops the I/O structure
178  * @param timer a timer previously created with timer_create
179  * @param usecs the timer interval
180  * @param uarg the user-defined pointer to be passed in the callback
181  * @param callback the callback to invoke
182  */
183 typedef int (*lcb_io_timer_schedule_fn)
184         (lcb_io_opt_t iops, void *timer,
185                 lcb_U32 usecs,
186                 void *uarg,
187                 lcb_ioE_callback callback);
188 
189 /**@}*/
190 
191 
192 /**@name Event Handle Callbacks
193  * @{*/
194 
195 /**
196  * @brief Create a new event handle.
197  *
198  * An event object may be used to monitor a socket for given I/O readiness events
199  * @param iops the I/O structure.
200  * @return a new event handle.
201  * The handle may then be associated with a
202  * socket and watched (via lcb_ioE_event_watch_fn) for I/O readiness.
203  */
204 typedef void *(*lcb_ioE_event_create_fn)
205         (lcb_io_opt_t iops);
206 
207 /**
208  * @brief Destroy an event handle
209  *
210  * Destroy an event object. The object must not be active.
211  * @param iops the I/O structure
212  * @param event the event to free
213  */
214 typedef void (*lcb_ioE_event_destroy_fn)
215         (lcb_io_opt_t iops, void *event);
216 
217 /**
218  * @deprecated lcb_ioE_event_watch_fn() should be used with `0` for events
219  * @brief Cancel pending callbacks and unwatch a handle.
220  *
221  * @param iops the I/O structure
222  * @param sock the socket associated with the event
223  * @param event the opaque event object
224  *
225  * This function may be called multiple times and shall not fail even if the
226  * event is already inactive.
227  */
228 typedef void (*lcb_ioE_event_cancel_fn)
229         (lcb_io_opt_t iops, lcb_socket_t sock, void *event);
230 
231 
232 /** Data is available for reading */
233 #define LCB_READ_EVENT 0x02
234 /** Data can be written */
235 #define LCB_WRITE_EVENT 0x04
236 /** Exceptional condition ocurred on socket */
237 #define LCB_ERROR_EVENT 0x08
238 #define LCB_RW_EVENT (LCB_READ_EVENT|LCB_WRITE_EVENT)
239 
240 /**
241  * Associate an event with a socket, requesting notification when one of
242  * the events specified in 'flags' becomes available on the socket.
243  *
244  * @param iops the IO context
245  * @param socket the socket to watch
246  * @param event the event to associate with the socket. If this parameter is
247  * @param evflags a bitflag of events to watch. This is one of LCB_READ_EVENT,
248  * LCB_WRITE_EVENT, or LCB_RW_EVENT.
249  * If this value is `0` then existing events shall be cancelled on the
250  * socket.
251  *
252  * Note that the callback may _also_ receive LCB_ERROR_EVENT but this cannot
253  * be requested as an event to watch for.
254  *
255  * @param uarg a user defined pointer to be passed to the callback
256  * @param callback the callback to invoke when one of the events becomes
257  * ready.
258  *
259  * @attention
260  * It shall be legal to call this routine multiple times without having to call
261  * the lcb_ioE_event_cancel_fn(). The cancel function should in fact be implemented
262  * via passing a `0` to the `evflags` parameter, effectively clearing the
263  * event.
264  */
265 typedef int (*lcb_ioE_event_watch_fn)
266         (lcb_io_opt_t iops,
267                 lcb_socket_t socket,
268                 void *event,
269                 short evflags,
270                 void *uarg,
271                 lcb_ioE_callback callback);
272 
273 /**@}*/
274 
275 /**@name BSD-API I/O Routines
276  * @{*/
277 
278 /**
279  * @brief Receive data into a single buffer
280  * @see `recv(2)` socket API call.
281  */
282 typedef lcb_SSIZE (*lcb_ioE_recv_fn)
283         (lcb_io_opt_t iops, lcb_socket_t sock, void *target_buf,
284                 lcb_SIZE buflen, int _unused_flags);
285 
286 /** @brief Send data from a single buffer.
287  * @see `send(2)` on POSIX
288  */
289 typedef lcb_SSIZE (*lcb_ioE_send_fn)
290         (lcb_io_opt_t iops, lcb_socket_t sock, const void *srcbuf,
291                 lcb_SIZE buflen, int _ignored);
292 
293 /**@brief Read data into a series of buffers.
294  * @see the `recvmsg(2)` function on POSIX */
295 typedef lcb_SSIZE (*lcb_ioE_recvv_fn)
296         (lcb_io_opt_t iops, lcb_socket_t sock, lcb_IOV *iov, lcb_SIZE niov);
297 
298 /**@brief Write data from multiple buffers.
299  * @see the `sendmsg(2)` function on POSIX */
300 typedef lcb_SSIZE (*lcb_ioE_sendv_fn)
301         (lcb_io_opt_t iops, lcb_socket_t sock, lcb_IOV *iov, lcb_SIZE niov);
302 
303 /**@brief Create a new socket.
304  * @see `socket(2)` on POSIX */
305 typedef lcb_socket_t (*lcb_ioE_socket_fn)
306         (lcb_io_opt_t iops, int domain, int type, int protocol);
307 
308 /**@brief Connect a created socket
309  * @see `connect(2)` on POSIX */
310 typedef int (*lcb_ioE_connect_fn)
311         (lcb_io_opt_t iops,
312                 lcb_socket_t sock,
313                 const struct sockaddr *dst,
314                 unsigned int addrlen);
315 
316 /** @internal */
317 typedef int (*lcb_ioE_bind_fn)
318         (lcb_io_opt_t iops,
319                 lcb_socket_t sock,
320                 const struct sockaddr *srcaddr,
321                 unsigned int addrlen);
322 
323 /** @internal */
324 typedef int (*lcb_ioE_listen_fn)
325         (lcb_io_opt_t iops,
326                 lcb_socket_t bound_sock,
327                 unsigned int queuelen);
328 
329 /** @internal */
330 typedef lcb_socket_t (*lcb_ioE_accept_fn)
331         (lcb_io_opt_t iops,
332                 lcb_socket_t lsnsock);
333 
334 /** @brief Close a socket
335  * @see `close(2)` and `shutdown(2)` */
336 typedef void (*lcb_ioE_close_fn)
337         (lcb_io_opt_t iops, lcb_socket_t sock);
338 
339 
340 /**
341  * While checking the socket, treat pending data as an _error_.
342  * This flag will be _missing_ if the socket participates in a protocol
343  * where unsolicited data is possible.
344  *
345  * Currently Couchbase does not provide such a protocol (at least not one where
346  * sockets are placed in a pool), but it may in the future.
347  *
348  * This may be passed as a `flags` option to lcb_ioE_chkclosed_fn
349  */
350 #define LCB_IO_SOCKCHECK_PEND_IS_ERROR 1
351 
352 #define LCB_IO_SOCKCHECK_STATUS_CLOSED 1
353 #define LCB_IO_SOCKCHECK_STATUS_OK 0
354 #define LCB_IO_SOCKCHECK_STATUS_UNKNOWN -1
355 
356 /**@brief Check if a socket has been closed or not. This is used to check
357  * a socket's state after a period of inactivity.
358  *
359  *
360  * @param iops The iops
361  * @param sock The socket to check
362  * @param flags A bit set of options.
363  * @return A value greater than 0 if the socket _is_ closed, 0 if the socket
364  * has not been closed, or a negative number, if the status could not be
365  * determined within the given constraints (for example, if `flags` did not
366  * specify `LCB_IO_SOCKCHECK_PEND_IS_ERROR`, and the implementation does not
367  * have a way to check status otherwise.
368  *
369  * @since 2.4.4
370  */
371 typedef int (*lcb_ioE_chkclosed_fn)
372         (lcb_io_opt_t iops, lcb_socket_t sock, int flags);
373 
374 
375 /** For use with `io{E,C}_cntl_fn`, indicates the setting should be retrieved */
376 #define LCB_IO_CNTL_GET 0
377 /** For use with lcb_io{E,C}_cntl_fn`, indicates the setting should be modified */
378 #define LCB_IO_CNTL_SET 1
379 
380 /** Disable Nagle's algorithm (use an int) */
381 #define LCB_IO_CNTL_TCP_NODELAY 1
382 
383 /** Enable/Disable TCP Keepalive */
384 #define LCB_IO_CNTL_TCP_KEEPALIVE 2
385 
386 /**
387  * @brief Execute a specificied operation on a socket.
388  * @param iops The iops
389  * @param sock The socket
390  * @param mode The mode, can be @ref LCB_IO_CNTL_GET or @ref LCB_IO_CNTL_SET
391  * @param option The option to access
392  * @param[in,out] arg the argument for the option
393  * @return zero on success, nonzero on failure.
394  */
395 typedef int (*lcb_ioE_cntl_fn)
396         (lcb_io_opt_t iops, lcb_socket_t sock, int mode, int option, void *arg);
397 /**@}*/
398 
399 
400 struct ringbuffer_st;
401 struct lcb_connection_st;
402 struct lcbio_SOCKET;
403 
404 /** @deprecated Ringbuffers are no longer used this way by the library for I/O */
405 struct lcb_buf_info {
406     char *root;
407     lcb_SIZE size;
408     struct ringbuffer_st *ringbuffer;
409     struct lcb_iovec_st iov[2];
410 };
411 
412 /**
413  * @brief Socket handle for completion-based I/O
414  *
415  * The sockdata structure is analoguous to an `lcb_socket_t` returned by
416  * the E-model I/O.
417  */
418 typedef struct lcb_sockdata_st {
419     lcb_socket_t socket; /**< System socket, for informational purposes */
420     lcb_io_opt_t parent; /**< Parent I/O context */
421     struct lcbio_SOCKET *lcbconn; /**< Internal socket equivalent */
422     int closed; /**< @deprecated No longer used by the library */
423     int is_reading; /**< Internally used by lcbio */
424     struct lcb_buf_info read_buffer; /**< @deprecated No longer used by the library */
425 } lcb_sockdata_t;
426 
427 /** @deprecated */
428 typedef struct lcb_io_writebuf_st {
429     struct lcb_io_opt_st *parent;
430     struct lcb_buf_info buffer;
431 } lcb_io_writebuf_t;
432 
433 /**@name Completion Routines
434  * @{*/
435 
436 /**
437  * @brief Create a completion socket handle
438  *
439  * Create an opaque socket handle
440  * @param iops the IO context
441  * @param domain socket address family, e.g. AF_INET
442  * @param type the transport type, e.g. SOCK_STREAM
443  * @param protocol the IP protocol, e.g. IPPROTO_TCP
444  * @return a socket pointer or NULL on failure.
445  */
446 typedef lcb_sockdata_t* (*lcb_ioC_socket_fn)
447         (lcb_io_opt_t iops, int domain, int type, int protocol);
448 
449 /**
450  * @brief Callback to be invoked upon a connection result.
451  * Callback invoked for a connection result.
452  * @param socket the socket which is being connected
453  * @param status the status. 0 for success, nonzero on failure
454  */
455 typedef void (*lcb_io_connect_cb)(lcb_sockdata_t *socket, int status);
456 
457 /**
458  * @brief Request a connection for a socket
459  * @param iops the IO context
460  * @param sd the socket pointer
461  * @param dst the address to connect to
462  * @param naddr the size of the address len, e.g. sizeof(struct sockaddr_in)
463  * @param callback the callback to invoke when the connection status is determined
464  * @return 0 on success, nonzero if a connection could not be scheduled.
465  */
466 typedef int (*lcb_ioC_connect_fn)
467         (lcb_io_opt_t iops, lcb_sockdata_t *sd,
468                 const struct sockaddr *dst,
469                 unsigned int naddr,
470                 lcb_io_connect_cb callback);
471 
472 /**
473  * @brief Callback invoked when a new client connection has been established
474  * @param sd_server the server listen socket
475  * @param sd_client the new client socket
476  * @param status if there was an error accepting (in this case, sd_client is NULL
477  */
478 typedef void (lcb_ioC_serve_callback)
479         (lcb_sockdata_t *sd_server,
480                 lcb_sockdata_t *sd_client,
481                 int status);
482 
483 /**
484  * Specify that the socket start accepting connections. This should be called
485  * on a newly created non-connected socket
486  * @param iops the I/O context
487  * @param server_socket the socket used to listen with
488  * @param sockaddr the local address for listening
489  * @param callback the callback to invoke for each new connection
490  */
491 typedef int (*lcb_ioC_serve_fn)
492         (lcb_io_opt_t iops,
493                 lcb_sockdata_t *server_socket,
494                 const struct sockaddr *listen_addr,
495                 lcb_ioC_serve_callback callback);
496 
497 /**
498  * @brief Request address information on a connected socket
499  * @param iops the I/O context
500  * @param sock the socket from which to retrieve information
501  * @param ni a nameinfo structure to populate with the relevant details
502  */
503 typedef int (*lcb_ioC_nameinfo_fn)
504         (lcb_io_opt_t iops,
505                 lcb_sockdata_t *sock,
506                 struct lcb_nameinfo_st *ni);
507 
508 /**@deprecated*/
509 typedef void (*lcb_ioC_read_callback)(lcb_sockdata_t *sd, lcb_SSIZE nread);
510 #define lcb_io_read_cb lcb_ioC_read_callback
511 /**@deprecated See lcb_ioC_read2_fn(). Wrapped if not implemented*/
512 typedef int (*lcb_ioC_read_fn)(lcb_io_opt_t,lcb_sockdata_t*,lcb_ioC_read_callback);
513 /**@deprecated See lcb_ioC_write2_fn(). Wrapped if not implemented*/
514 typedef lcb_io_writebuf_t* (*lcb_ioC_wballoc_fn)(lcb_io_opt_t,lcb_sockdata_t *);
515 /**@deprecated See lcb_ioC_write2_fn(). Wrapped if not implemented */
516 typedef void (*lcb_ioC_wbfree_fn)(lcb_io_opt_t,lcb_sockdata_t*,lcb_io_writebuf_t*);
517 /**@deprecated See lcb_ioC_write2_fn(). This will be wrapped if not implemented */
518 typedef void (*lcb_ioC_write_callback)(lcb_sockdata_t*,lcb_io_writebuf_t*,int);
519 #define lcb_io_write_cb lcb_ioC_write_callback
520 
521 /**@deprecated*/
522 typedef int (*lcb_ioC_write_fn)
523         (lcb_io_opt_t,lcb_sockdata_t*,lcb_io_writebuf_t*,lcb_ioC_write_callback);
524 
525 
526 /**
527  * @brief Callback received when a buffer has been flushed
528  * @param sd the socket
529  * @param status nonzero on error
530  * @param arg the opaque handle passed in the write2 call
531  */
532 typedef void (*lcb_ioC_write2_callback)
533         (lcb_sockdata_t *sd,
534                 int status,
535                 void *arg);
536 
537 /**
538  * @brief Schedule a flush of a series of buffers to the network
539  *
540  * @param iops the I/O context
541  * @param sd the socket on which to send
542  * @param iov an array of IOV structures.
543  *        The buffers pointed to by the IOVs themselves (i.e. `iov->iov_len`)
544  *        **must** not be freed or modified until the callback has been invoked.
545  *        The storage for the IOVs themselves (i.e. the array passed in `iov`)
546  *        is copied internally to the implementation.
547  *
548  * @param niov the number of IOV structures within the array
549  * @param uarg an opaque pointer to be passed in the callback
550  * @param callback the callback to invoke. This will be called when the buffers
551  *        passed have either been completely flushed (and are no longer required)
552  *        or when an error has taken place.
553  */
554 typedef int (*lcb_ioC_write2_fn)
555         (lcb_io_opt_t iops,
556                 lcb_sockdata_t *sd,
557                 lcb_IOV *iov,
558                 lcb_SIZE niov,
559                 void *uarg,
560                 lcb_ioC_write2_callback callback);
561 
562 
563 /**
564  * @brief Callback invoked when a read has been completed
565  * @param sd the socket
566  * @param nread number of bytes read, or -1 on error
567  * @param arg user provided argument for callback.
568  */
569 typedef void (*lcb_ioC_read2_callback)
570         (lcb_sockdata_t *sd, lcb_SSIZE nread, void *arg);
571 /**
572  * @brief Schedule a read from the network
573  * @param iops the I/O context
574  * @param sd the socket on which to read
575  * @param iov an array of IOV structures
576  * @param niov the number of IOV structures within the array
577  * @param uarg a pointer passed to the callback
578  * @param callback the callback to invoke
579  * @return 0 on success, nonzero on error
580  *
581  * The IOV array itself shall copied (if needed) into the I/O implementation
582  * and thus does not need to be kept in memory after the function has been
583  * called. Note that the underlying buffers _do_ need to remain valid until
584  * the callback is received.
585  */
586 typedef int (*lcb_ioC_read2_fn)
587         (lcb_io_opt_t iops,
588                 lcb_sockdata_t *sd,
589                 lcb_IOV *iov,
590                 lcb_SIZE niov,
591                 void *uarg,
592                 lcb_ioC_read2_callback callback);
593 
594 /**
595  * @brief Asynchronously shutdown the socket.
596  *
597  * Request an asynchronous close for the specified socket. This merely releases
598  * control from the library over to the plugin for the specified socket and
599  * does _not_ actually imply that the resources have been closed.
600  *
601  * Notable, callbacks for read and write operations will _still_ be invoked
602  * in order to maintain proper resource deallocation. However the socket's
603  * closed field will be set to true.
604  *
605  * @param iops the I/O context
606  * @param sd the socket structure
607  */
608 typedef unsigned int (*lcb_ioC_close_fn)
609         (lcb_io_opt_t iops,
610                 lcb_sockdata_t *sd);
611 
612 /**
613  * This is the completion variant of @ref lcb_ioE_chkclosed_fn. See that
614  * function for details
615  *
616  * @param iops
617  * @param sd
618  * @param flags
619  * @return
620  */
621 typedef int (*lcb_ioC_chkclosed_fn)
622         (lcb_io_opt_t iops, lcb_sockdata_t *sd, int flags);
623 
624 /**
625  * @see lcb_ioE_cntl_fn.
626  *
627  * @param iops
628  * @param sd
629  * @param mode
630  * @param option
631  * @param arg
632  * @return
633  */
634 typedef int (*lcb_ioC_cntl_fn)
635         (lcb_io_opt_t iops, lcb_sockdata_t *sd, int mode, int option, void *arg);
636 
637 /**@}*/
638 
639 /**
640  * @brief Start the event loop
641  * @param iops The I/O context
642  *
643  * This should start polling for socket events on all registered watchers
644  * and scheduled events. This function should return either when there are
645  * no more timers or events pending, or when lcb_io_stop_fn() has been invoked.
646  */
647 typedef void (*lcb_io_start_fn)(lcb_io_opt_t iops);
648 
649 /**
650  * @brief Run a single iteration of the event loop without blocking. This
651  * is intended to be an optimization to allow scheduled I/O operations to
652  * complete without blocking the main thread
653  */
654 typedef void (*lcb_io_tick_fn)(lcb_io_opt_t iops);
655 
656 /**
657  * @brief Pause the event loop
658  * @param iops The I/O Context
659  *
660  * This function shall suspend the event loop, causing a current invocation
661  * to lcb_io_start_fn() to return as soon as possible
662  */
663 typedef void (*lcb_io_stop_fn)(lcb_io_opt_t iops);
664 
665 LCB_DEPRECATED(typedef void (*lcb_io_error_cb)(lcb_sockdata_t *socket));
666 
667 #define LCB_IOPS_BASE_FIELDS \
668     void *cookie; \
669     int error; \
670     int need_cleanup;
671 
672 struct lcb_iops_evented_st {
673     LCB_IOPS_BASE_FIELDS
674     LCB_IOPS_DEPRECATED(lcb_ioE_socket_fn socket);
675     LCB_IOPS_DEPRECATED(lcb_ioE_connect_fn connect);
676     LCB_IOPS_DEPRECATED(lcb_ioE_recv_fn recv);
677     LCB_IOPS_DEPRECATED(lcb_ioE_send_fn send);
678     LCB_IOPS_DEPRECATED(lcb_ioE_recvv_fn recvv);
679     LCB_IOPS_DEPRECATED(lcb_ioE_sendv_fn sendv);
680     LCB_IOPS_DEPRECATED(lcb_ioE_close_fn close);
681     LCB_IOPS_DEPRECATED(lcb_io_timer_create_fn create_timer);
682     LCB_IOPS_DEPRECATED(lcb_io_timer_destroy_fn destroy_timer);
683     LCB_IOPS_DEPRECATED(lcb_io_timer_cancel_fn delete_timer);
684     LCB_IOPS_DEPRECATED(lcb_io_timer_schedule_fn update_timer);
685     LCB_IOPS_DEPRECATED(lcb_ioE_event_create_fn create_event);
686     LCB_IOPS_DEPRECATED(lcb_ioE_event_destroy_fn destroy_event);
687     LCB_IOPS_DEPRECATED(lcb_ioE_event_watch_fn update_event);
688     LCB_IOPS_DEPRECATED(lcb_ioE_event_cancel_fn delete_event);
689     LCB_IOPS_DEPRECATED(lcb_io_stop_fn stop_event_loop);
690     LCB_IOPS_DEPRECATED(lcb_io_start_fn run_event_loop);
691 };
692 
693 struct lcb_iops_completion_st {
694     LCB_IOPS_BASE_FIELDS
695     LCB_IOPS_DEPRECATED(lcb_ioC_socket_fn create_socket);
696     LCB_IOPS_DEPRECATED(lcb_ioC_connect_fn start_connect);
697     LCB_IOPS_DEPRECATED(lcb_ioC_wballoc_fn create_writebuf);
698     LCB_IOPS_DEPRECATED(lcb_ioC_wbfree_fn release_writebuf);
699     LCB_IOPS_DEPRECATED(lcb_ioC_write_fn start_write);
700     LCB_IOPS_DEPRECATED(lcb_ioC_read_fn start_read);
701     LCB_IOPS_DEPRECATED(lcb_ioC_close_fn close_socket);
702     LCB_IOPS_DEPRECATED(lcb_io_timer_create_fn create_timer);
703     LCB_IOPS_DEPRECATED(lcb_io_timer_destroy_fn destroy_timer);
704     LCB_IOPS_DEPRECATED(lcb_io_timer_cancel_fn delete_timer);
705     LCB_IOPS_DEPRECATED(lcb_io_timer_schedule_fn update_timer);
706     LCB_IOPS_DEPRECATED(lcb_ioC_nameinfo_fn get_nameinfo);
707     void (*pad1)(void);
708     void (*pad2)(void);
709     LCB_IOPS_DEPRECATED(void (*send_error)(struct lcb_io_opt_st*, lcb_sockdata_t*,void(*)(lcb_sockdata_t*)));
710     LCB_IOPS_DEPRECATED(lcb_io_stop_fn stop_event_loop);
711     LCB_IOPS_DEPRECATED(lcb_io_start_fn run_event_loop);
712 };
713 
714 /** @brief Common functions for starting and stopping timers */
715 typedef struct lcb_timerprocs_st {
716     lcb_io_timer_create_fn create;
717     lcb_io_timer_destroy_fn destroy;
718     lcb_io_timer_cancel_fn cancel;
719     lcb_io_timer_schedule_fn schedule;
720 } lcb_timer_procs;
721 
722 /** @brief Common functions for starting and stopping the event loop */
723 typedef struct lcb_loopprocs_st {
724     lcb_io_start_fn start;
725     lcb_io_stop_fn stop;
726     lcb_io_tick_fn tick;
727 } lcb_loop_procs;
728 
729 /** @brief Functions wrapping the Berkeley Socket API */
730 typedef struct lcb_bsdprocs_st {
731     lcb_ioE_socket_fn socket0;
732     lcb_ioE_connect_fn connect0;
733     lcb_ioE_recv_fn recv;
734     lcb_ioE_recvv_fn recvv;
735     lcb_ioE_send_fn send;
736     lcb_ioE_sendv_fn sendv;
737     lcb_ioE_close_fn close;
738     lcb_ioE_bind_fn bind;
739     lcb_ioE_listen_fn listen;
740     lcb_ioE_accept_fn accept;
741     lcb_ioE_chkclosed_fn is_closed;
742     lcb_ioE_cntl_fn cntl;
743 } lcb_bsd_procs;
744 
745 /** @brief Functions handling socket watcher events */
746 typedef struct lcb_evprocs_st {
747     lcb_ioE_event_create_fn create;
748     lcb_ioE_event_destroy_fn destroy;
749     lcb_ioE_event_cancel_fn cancel;
750     lcb_ioE_event_watch_fn watch;
751 } lcb_ev_procs;
752 
753 /** @brief Functions for completion-based I/O */
754 typedef struct {
755     lcb_ioC_socket_fn socket;
756     lcb_ioC_close_fn close;
757     lcb_ioC_read_fn read;
758     lcb_ioC_connect_fn connect;
759     lcb_ioC_wballoc_fn wballoc;
760     lcb_ioC_wbfree_fn wbfree;
761     lcb_ioC_write_fn write;
762     lcb_ioC_write2_fn write2;
763     lcb_ioC_read2_fn read2;
764     lcb_ioC_serve_fn serve;
765     lcb_ioC_nameinfo_fn nameinfo;
766     lcb_ioC_chkclosed_fn is_closed;
767     lcb_ioC_cntl_fn cntl;
768 } lcb_completion_procs;
769 
770 /**
771  * Enumeration defining the I/O model
772  */
773 typedef enum {
774     LCB_IOMODEL_EVENT, /**< Event/Poll style */
775     LCB_IOMODEL_COMPLETION /**< IOCP/Completion style */
776 } lcb_iomodel_t;
777 
778 /**
779  * @param version the ABI/API version for the proc structures. Note that
780  *  ABI is forward compatible for all proc structures, meaning that newer
781  *  versions will always extend new fields and never replace existing ones.
782  *  However in order to avoid a situation where a newer version of a plugin
783  *  is loaded against an older version of the library (in which case the plugin
784  *  will assume the proc table size is actually bigger than it is) the version
785  *  serves as an indicator for this. The version actually passed is defined
786  *  in `LCB_IOPROCS_VERSION`
787  *
788  * @param loop_procs a table to be set to basic loop control routines
789  * @param timer_procs a table to be set to the timer routines
790  * @param bsd_procs a table to be set to BSD socket API routines
791  * @param ev_procs a table to be set to event watcher routines
792  * @param completion_procs a table to be set to completion routines
793  * @param iomodel the I/O model to be used. If this is `LCB_IOMODEL_COMPLETION`
794  * then the contents of `bsd_procs` will be ignored and `completion_procs` must
795  * be populated. If the mode is `LCB_IOMODEL_EVENT` then the `bsd_procs` must be
796  * populated and `completion_procs` is ignored.
797  *
798  * Important to note that internally the `ev`, `bsd`, and `completion` field are
799  * defined as a union, thus
800  * @code{.c}
801  * union {
802  *     struct {
803  *         lcb_bsd_procs;
804  *         lcb_ev_procs;
805  *     } event;
806  *     struct lcb_completion_procs completion;
807  * }
808  * @endcode
809  * thus setting both fields will actually clobber.
810  *
811  * @attention
812  * Note that the library takes ownership of the passed tables and it should
813  * not be controlled or accessed by the plugin.
814  *
815  * @attention
816  * This function may not have any side effects as it may be called
817  * multiple times.
818  *
819  * As opposed to the v0 and v1 IOPS structures that require a table to be
820  * populated and returned, the v2 IOPS works differently. Specifically, the
821  * IOPS population happens at multiple stages:
822  *
823  * 1. The base structure is returned, i.e. `lcb_create_NAME_iops` where _NAME_
824  *    is the name of the plugin
825  *
826  * 2. Once the structure is returned, LCB shall invoke the `v.v2.get_procs()`
827  *    function. The callback is responsible for populating the relevant fields.
828  *
829  * Note that the old `v0` and `v1` fields are now proxied via this mechanism.
830  * It _is_ possible to still monkey-patch the IO routines, but ensure the
831  * monkey patching takes place _before_ the instance is created (as the
832  * instance will initialize its own IO Table); thus, e.g.
833  * @code{.c}
834  * static void monkey_proc_fn(...) {
835  *     //
836  * }
837  *
838  * static void monkey_patch_io(lcb_io_opt_t io) {
839  *     io->v.v0.get_procs = monkey_proc_fn;
840  * }
841  *
842  * int main(void) {
843  *     lcb_create_st options;
844  *     lcb_t instance;
845  *     lcb_io_opt_t io;
846  *     lcb_create_iops(&io, NULL);
847  *     monkey_patch_io(io);
848  *     options.v.v0.io = io;
849  *     lcb_create(&instance, &options);
850  *     // ...
851  * }
852  * @endcode
853  *
854  * Typically the `get_procs` function will only be called once, and this will
855  * happen from within lcb_create(). Thus in order to monkey patch you must
856  * ensure that initially the `get_procs` function itself is first supplanted
857  * and then return your customized I/O routines from your own `get_procs` (in
858  * this example, `monkey_proc_fn()`)
859  *
860  */
861 typedef void (*lcb_io_procs_fn)
862         (int version,
863                 lcb_loop_procs *loop_procs,
864                 lcb_timer_procs *timer_procs,
865                 lcb_bsd_procs *bsd_procs,
866                 lcb_ev_procs *ev_procs,
867                 lcb_completion_procs *completion_procs,
868                 lcb_iomodel_t *iomodel);
869 
870 struct lcbio_TABLE;
871 struct lcb_iops2_st {
872     LCB_IOPS_BASE_FIELDS
873     lcb_io_procs_fn get_procs;
874     struct lcbio_TABLE *iot;
875 };
876 
877 /* This is here to provide backwards compatibility with older (broken) clients
878  * which attempt to 'subclass' the select plugin, or similar. In this case we
879  * provide 17 callback fields (unused here) which the plugin implementation
880  * may set, so that the older code can continue to function without upgrading
881  * the client to a newer version. This should not be used except by internal
882  * plugins; specifically the ABI layout of this field is subject to change
883  * (for example, additional fields may be added or existing fields may be
884  * renamed/removed) without notice.
885  */
886 typedef void (*lcb__iops3fndummy)(void);
887 struct lcb_iops3_st {
888     LCB_IOPS_BASE_FIELDS
889     lcb__iops3fndummy pads[17];
890     lcb_io_procs_fn get_procs;
891     struct lcbio_TABLE *iot;
892 };
893 
894 /**
895  * This number is bumped up each time a new field is added to any of the
896  * function tables. This number is backwards compatible (i.e. version 3 contains
897  * all the fields of version 2, and some additional ones)
898  */
899 #define LCB_IOPROCS_VERSION 4
900 
901 #define LCB_IOPS_BASEFLD(iops, fld) ((iops)->v.base).fld
902 #define LCB_IOPS_ERRNO(iops) LCB_IOPS_BASEFLD(iops, error)
903 
904 struct lcb_io_opt_st {
905     int version;
906     void *dlhandle;
907     void (*destructor)(struct lcb_io_opt_st *iops);
908     union {
909         struct {
910             LCB_IOPS_BASE_FIELDS
911         } base;
912 
913         /** These two names are deprecated internally */
914         struct lcb_iops_evented_st v0;
915         struct lcb_iops_completion_st v1;
916         struct lcb_iops2_st v2;
917         struct lcb_iops3_st v3;
918     } v;
919 };
920 
921 /**
922  * @brief Signature for a loadable plugin's IOPS initializer
923  *
924  * @param version the plugin init API version. This will be 0 for this function
925  * @param io a pointer to be set to the I/O table
926  * @param cookie a user-defined argument passed to the I/O initializer
927  * @return LCB_SUCCESS on success, an error on failure
928  */
929 typedef lcb_error_t (*lcb_io_create_fn)
930         (int version, lcb_io_opt_t *io, void *cookie);
931 
932 
933 /**
934  * @volatile
935  *
936  * This is an alternative to copying the 'bsdio-inl.c' file around. It is
937  * designed specifically for the @ref lcb_io_procs_fn function and will do the
938  * job of applying the current _runtime_ version of the default event-based I/O
939  * implementation.
940  *
941  * e.g.
942  * @code{.c}
943  * static void getprocs_impl(int version, lcb_loop_procs *loop_procs,
944  *      lcb_timer_procs *timer_procs, lcb_bsd_procs *bsd_procs,
945  *      lcb_ev_procs *ev_procs, lcb_completion_procs *completion_procs,
946  *      lcb_iomodel_t *iomodel) {
947  *
948  *      // do stuff normally
949  *      // ..
950  *      // install the default I/O handlers:
951  *      lcb_iops_wire_bsd_impl2(bsd_procs, version);
952  * @endcode
953  *
954  * Use this function with care, and understand the implications between using
955  * this API call and embedding the `bsdio-inl.c` source file. Specifically:
956  *
957  * - If your application is using an _older_ version of the library, this
958  *   implementation may contain bugs not present in the version you compiled
959  *   against (and an embedded version may be newer)
960  * - If your application is using a _newer_ version, there may be some additional
961  *   I/O functions which you may wish to wrap or rather not implement at all,
962  *   but will be implemented if you call this function.
963  */
964 LIBCOUCHBASE_API
965 void
966 lcb_iops_wire_bsd_impl2(lcb_bsd_procs *procs, int version);
967 
968 /******************************************************************************
969  ******************************************************************************
970  ** IO CREATION                                                              **
971  ******************************************************************************
972  ******************************************************************************/
973 
974 /**
975  * @brief Built-in I/O plugins
976  * @committed
977  */
978 typedef enum {
979     LCB_IO_OPS_INVALID = 0x00, /**< @internal */
980     LCB_IO_OPS_DEFAULT = 0x01, /**< @internal */
981 
982     /** Integrate with the libevent loop. See lcb_create_libevent_io_opts() */
983     LCB_IO_OPS_LIBEVENT = 0x02,
984     LCB_IO_OPS_WINSOCK = 0x03, /**< @internal */
985     LCB_IO_OPS_LIBEV = 0x04,
986     LCB_IO_OPS_SELECT = 0x05,
987     LCB_IO_OPS_WINIOCP = 0x06,
988     LCB_IO_OPS_LIBUV = 0x07
989 } lcb_io_ops_type_t;
990 
991 /** @brief IO Creation for builtin plugins */
992 typedef struct {
993     lcb_io_ops_type_t type; /**< The predefined type you want to create */
994     void *cookie; /**< Plugin-specific argument */
995 } lcb_IOCREATEOPTS_BUILTIN;
996 
997 #ifndef __LCB_DOXYGEN__
998 /* These are mostly internal structures which may be in use by older applications.*/
999 typedef struct { const char *sofile; const char *symbol; void *cookie; } lcb_IOCREATEOPTS_DSO;
1000 typedef struct { lcb_io_create_fn create; void *cookie; } lcb_IOCREATEOPS_FUNCTIONPOINTER;
1001 #endif
1002 
1003 /** @uncommitted */
1004 struct lcb_create_io_ops_st {
1005     int version;
1006     union {
1007         lcb_IOCREATEOPTS_BUILTIN v0;
1008         lcb_IOCREATEOPTS_DSO v1;
1009         lcb_IOCREATEOPS_FUNCTIONPOINTER v2;
1010     } v;
1011 };
1012 
1013 /**
1014  * Create a new instance of one of the library-supplied io ops types.
1015  *
1016  * This function should only be used if you wish to override/customize the
1017  * default I/O plugin behavior; for example to select a specific implementation
1018  * (e.g. always for the _select_ plugin) and/or to integrate
1019  * a builtin plugin with your own application (e.g. pass an existing `event_base`
1020  * structure to the _libevent_ plugin).
1021  *
1022  * If you _do_ use this function, then you must call lcb_destroy_io_ops() on
1023  * the plugin handle once it is no longer required (and no instance is using
1024  * it).
1025  *
1026  * Whether a single `lcb_io_opt_t` may be used by multiple instances at once
1027  * is dependent on the specific implementation, but as a general rule it should
1028  * be assumed to be unsafe.
1029  *
1030  * @param[out] op The newly created io ops structure
1031  * @param options How to create the io ops structure
1032  * @return @ref LCB_SUCCESS on success
1033  * @uncommitted
1034  */
1035 LIBCOUCHBASE_API
1036 lcb_error_t lcb_create_io_ops(lcb_io_opt_t *op, const struct lcb_create_io_ops_st *options);
1037 
1038 /**
1039  * Destroy the plugin handle created by lcb_create_io_ops()
1040  * @param op ops structure
1041  * @return LCB_SUCCESS on success
1042  * @uncommitted
1043  */
1044 LIBCOUCHBASE_API
1045 lcb_error_t lcb_destroy_io_ops(lcb_io_opt_t op);
1046 
1047 #ifdef __cplusplus
1048 }
1049 #endif
1050 
1051 /**@}*/
1052 
1053 #endif
1054