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