Changeset 988 for vendor/current/lib/tsocket
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- Location:
- vendor/current/lib/tsocket
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/lib/tsocket/tsocket.h
r860 r988 628 628 TALLOC_CTX *mem_ctx); 629 629 630 #ifdef DOXYGEN 631 /** 632 * @brief Wrap an existing file descriptors into the tdgram abstraction. 633 * 634 * You can use this function to wrap an existing file descriptors into the 635 * tdgram abstraction. After that you're not able to use this file descriptor 636 * for anything else. The file descriptor will be closed when the stream gets 637 * freed. If you still want to use the fd you have have to create a duplicate. 638 * 639 * @param[in] mem_ctx The talloc memory context to use. 640 * 641 * @param[in] fd The non blocking fd to use! 642 * 643 * @param[out] dgram A pointer to store an allocated tdgram_context. 644 * 645 * @return 0 on success, -1 on error. 646 * 647 * Example: 648 * @code 649 * fd2 = dup(fd); 650 * rc = tdgram_bsd_existing_socket(mem_ctx, fd2, &tdgram); 651 * if (rc < 0) { 652 * return; 653 * } 654 * @endcode 655 * 656 * @warning This is an internal function. You should read the code to fully 657 * understand it if you plan to use it. 658 */ 659 int tdgram_bsd_existing_socket(TALLOC_CTX *mem_ctx, 660 int fd, 661 struct tdgram_context **dgram); 662 #else 663 int _tdgram_bsd_existing_socket(TALLOC_CTX *mem_ctx, 664 int fd, 665 struct tdgram_context **_dgram, 666 const char *location); 667 #define tdgram_bsd_existing_socket(mem_ctx, fd, dgram) \ 668 _tdgram_bsd_existing_socket(mem_ctx, fd, dgram, \ 669 __location__) 670 #endif 671 630 672 /** 631 673 * @brief Request a syscall optimization for tdgram_recvfrom_send() … … 664 706 * 665 707 * @return 0 on success, -1 on error with errno set. 708 * 709 * @see tdgram_inet_udp_broadcast_socket() 666 710 */ 667 711 int tdgram_inet_udp_socket(const struct tsocket_address *local, … … 677 721 #define tdgram_inet_udp_socket(local, remote, mem_ctx, dgram) \ 678 722 _tdgram_inet_udp_socket(local, remote, mem_ctx, dgram, __location__) 723 #endif 724 725 #ifdef DOXYGEN 726 /** 727 * @brief Create a tdgram_context for a ipv4 UDP broadcast (and unicast) communication. 728 * 729 * @param[in] local An 'inet' (ipv4 only) tsocket_address for the local endpoint. 730 * 731 * @param[in] mem_ctx The talloc memory context to use. 732 * 733 * @param[in] dgram The tdgram_context pointer to setup the udp 734 * communication. The function will allocate the memory. 735 * 736 * @return 0 on success, -1 on error with errno set. 737 * 738 * @see tdgram_inet_udp_socket() 739 */ 740 int tdgram_inet_udp_broadcast_socket(const struct tsocket_address *local, 741 TALLOC_CTX *mem_ctx, 742 struct tdgram_context **dgram); 743 #else 744 int _tdgram_inet_udp_broadcast_socket(const struct tsocket_address *local, 745 TALLOC_CTX *mem_ctx, 746 struct tdgram_context **dgram, 747 const char *location); 748 #define tdgram_inet_udp_broadcast_socket(local, mem_ctx, dgram) \ 749 _tdgram_inet_udp_broadcast_socket(local, mem_ctx, dgram, __location__) 679 750 #endif 680 751 … … 898 969 */ 899 970 int tsocket_address_bsd_from_sockaddr(TALLOC_CTX *mem_ctx, 900 struct sockaddr *sa,971 const struct sockaddr *sa, 901 972 size_t sa_socklen, 902 973 struct tsocket_address **addr); 903 974 #else 904 975 int _tsocket_address_bsd_from_sockaddr(TALLOC_CTX *mem_ctx, 905 struct sockaddr *sa,976 const struct sockaddr *sa, 906 977 size_t sa_socklen, 907 978 struct tsocket_address **_addr, -
vendor/current/lib/tsocket/tsocket_bsd.c
r860 r988 27 27 #include "tsocket.h" 28 28 #include "tsocket_internal.h" 29 #include "lib/util/iov_buf.h" 30 #include "lib/util/blocking.h" 29 31 30 32 static int tsocket_bsd_error_from_errno(int ret, … … 57 59 58 60 if (sys_errno == EAGAIN) { 61 *retry = true; 62 return sys_errno; 63 } 64 65 /* ENOMEM is retryable on Solaris/illumos, and possibly other systems. */ 66 if (sys_errno == ENOMEM) { 59 67 *retry = true; 60 68 return sys_errno; … … 78 86 int num_fds = 0; 79 87 80 int result, flags; 88 int result; 89 bool ok; 81 90 82 91 if (fd == -1) { … … 103 112 } 104 113 105 /* fd should be nonblocking. */ 106 107 #ifdef O_NONBLOCK 108 #define FLAG_TO_SET O_NONBLOCK 109 #else 110 #ifdef SYSV 111 #define FLAG_TO_SET O_NDELAY 112 #else /* BSD */ 113 #define FLAG_TO_SET FNDELAY 114 #endif 115 #endif 116 117 if ((flags = fcntl(fd, F_GETFL)) == -1) { 114 result = set_blocking(fd, false); 115 if (result == -1) { 118 116 goto fail; 119 117 } 120 118 121 flags |= FLAG_TO_SET;122 if ( fcntl(fd, F_SETFL, flags) == -1) {119 ok = smb_set_close_on_exec(fd); 120 if (!ok) { 123 121 goto fail; 124 122 } 125 123 126 #undef FLAG_TO_SET127 128 /* fd should be closed on exec() */129 #ifdef FD_CLOEXEC130 result = flags = fcntl(fd, F_GETFD, 0);131 if (flags >= 0) {132 flags |= FD_CLOEXEC;133 result = fcntl(fd, F_SETFD, flags);134 }135 if (result < 0) {136 goto fail;137 }138 #endif139 124 return fd; 140 125 … … 147 132 return -1; 148 133 } 134 135 #ifdef HAVE_LINUX_RTNETLINK_H 136 /** 137 * Get the amount of pending bytes from a netlink socket 138 * 139 * For some reason netlink sockets don't support querying the amount of pending 140 * data via ioctl with FIONREAD, which is what we use in tsocket_bsd_pending() 141 * below. 142 * 143 * We know we are on Linux as we're using netlink, which means we have a working 144 * MSG_TRUNC flag to recvmsg() as well, so we use that together with MSG_PEEK. 145 **/ 146 static ssize_t tsocket_bsd_netlink_pending(int fd) 147 { 148 struct iovec iov; 149 struct msghdr msg; 150 char buf[1]; 151 152 iov = (struct iovec) { 153 .iov_base = buf, 154 .iov_len = sizeof(buf) 155 }; 156 157 msg = (struct msghdr) { 158 .msg_iov = &iov, 159 .msg_iovlen = 1 160 }; 161 162 return recvmsg(fd, &msg, MSG_PEEK | MSG_TRUNC); 163 } 164 #else 165 static ssize_t tsocket_bsd_netlink_pending(int fd) 166 { 167 errno = ENOSYS; 168 return -1; 169 } 170 #endif 149 171 150 172 static ssize_t tsocket_bsd_pending(int fd) … … 204 226 205 227 int _tsocket_address_bsd_from_sockaddr(TALLOC_CTX *mem_ctx, 206 struct sockaddr *sa,228 const struct sockaddr *sa, 207 229 size_t sa_socklen, 208 230 struct tsocket_address **_addr, … … 384 406 } 385 407 386 snprintf(port_str, sizeof(port_str) - 1, "%u", port);408 snprintf(port_str, sizeof(port_str), "%u", port); 387 409 388 410 ret = getaddrinfo(addr, port_str, &hints, &result); … … 656 678 struct tevent_fd *fde; 657 679 bool optimize_recvfrom; 680 bool netlink; 658 681 659 682 void *readable_private; … … 813 836 struct tdgram_bsd_recvfrom_state { 814 837 struct tdgram_context *dgram; 815 838 bool first_try; 816 839 uint8_t *buf; 817 840 size_t len; … … 847 870 848 871 state->dgram = dgram; 872 state->first_try= true; 849 873 state->buf = NULL; 850 874 state->len = 0; … … 870 894 * 871 895 * This is needed because in most cases 872 * we prefer rto flush send buffers before896 * we prefer to flush send buffers before 873 897 * receiving incoming requests. 874 898 */ … … 907 931 bool retry; 908 932 909 ret = tsocket_bsd_pending(bsds->fd); 910 if (ret == 0) { 933 if (bsds->netlink) { 934 ret = tsocket_bsd_netlink_pending(bsds->fd); 935 } else { 936 ret = tsocket_bsd_pending(bsds->fd); 937 } 938 939 if (state->first_try && ret == 0) { 940 state->first_try = false; 911 941 /* retry later */ 912 942 return; 913 943 } 944 state->first_try = false; 945 914 946 err = tsocket_bsd_error_from_errno(ret, errno, &retry); 915 947 if (retry) { … … 921 953 } 922 954 955 /* note that 'ret' can be 0 here */ 923 956 state->buf = talloc_array(state, uint8_t, ret); 924 957 if (tevent_req_nomem(state->buf, req)) { … … 1098 1131 return; 1099 1132 } 1133 1134 if (err == EMSGSIZE) { 1135 /* round up in 1K increments */ 1136 int bufsize = ((state->len + 1023) & (~1023)); 1137 1138 ret = setsockopt(bsds->fd, SOL_SOCKET, SO_SNDBUF, &bufsize, 1139 sizeof(bufsize)); 1140 if (ret == 0) { 1141 /* 1142 * We do the retry here, rather then via the 1143 * handler, as we only want to retry once for 1144 * this condition, so if there is a mismatch 1145 * between what setsockopt() accepts and what can 1146 * actually be sent, we do not end up in a 1147 * loop. 1148 */ 1149 1150 ret = sendto(bsds->fd, state->buf, state->len, 1151 0, sa, sa_socklen); 1152 err = tsocket_bsd_error_from_errno(ret, errno, &retry); 1153 if (retry) { /* retry later */ 1154 return; 1155 } 1156 } 1157 } 1158 1100 1159 if (tevent_req_error(req, err)) { 1101 1160 return; … … 1373 1432 } 1374 1433 1434 int _tdgram_bsd_existing_socket(TALLOC_CTX *mem_ctx, 1435 int fd, 1436 struct tdgram_context **_dgram, 1437 const char *location) 1438 { 1439 struct tdgram_context *dgram; 1440 struct tdgram_bsd *bsds; 1441 #ifdef HAVE_LINUX_RTNETLINK_H 1442 int result; 1443 struct sockaddr sa; 1444 socklen_t sa_len = sizeof(struct sockaddr); 1445 #endif 1446 1447 dgram = tdgram_context_create(mem_ctx, 1448 &tdgram_bsd_ops, 1449 &bsds, 1450 struct tdgram_bsd, 1451 location); 1452 if (!dgram) { 1453 return -1; 1454 } 1455 ZERO_STRUCTP(bsds); 1456 bsds->fd = fd; 1457 talloc_set_destructor(bsds, tdgram_bsd_destructor); 1458 1459 *_dgram = dgram; 1460 1461 #ifdef HAVE_LINUX_RTNETLINK_H 1462 /* 1463 * Try to determine the protocol family and remember if it's 1464 * AF_NETLINK. We don't care if this fails. 1465 */ 1466 result = getsockname(fd, &sa, &sa_len); 1467 if (result == 0 && sa.sa_family == AF_NETLINK) { 1468 bsds->netlink = true; 1469 } 1470 #endif 1471 1472 return 0; 1473 } 1474 1375 1475 int _tdgram_inet_udp_socket(const struct tsocket_address *local, 1376 1476 const struct tsocket_address *remote, … … 1397 1497 1398 1498 ret = tdgram_bsd_dgram_socket(local, remote, false, 1499 mem_ctx, dgram, location); 1500 1501 return ret; 1502 } 1503 1504 int _tdgram_inet_udp_broadcast_socket(const struct tsocket_address *local, 1505 TALLOC_CTX *mem_ctx, 1506 struct tdgram_context **dgram, 1507 const char *location) 1508 { 1509 struct tsocket_address_bsd *lbsda = 1510 talloc_get_type_abort(local->private_data, 1511 struct tsocket_address_bsd); 1512 int ret; 1513 1514 switch (lbsda->u.sa.sa_family) { 1515 case AF_INET: 1516 break; 1517 #ifdef HAVE_IPV6 1518 case AF_INET6: 1519 /* only ipv4 */ 1520 errno = EINVAL; 1521 return -1; 1522 #endif 1523 default: 1524 errno = EINVAL; 1525 return -1; 1526 } 1527 1528 ret = tdgram_bsd_dgram_socket(local, NULL, true, 1399 1529 mem_ctx, dgram, location); 1400 1530 … … 1677 1807 * 1678 1808 * This is needed because in most cases 1679 * we prefer rto flush send buffers before1809 * we prefer to flush send buffers before 1680 1810 * receiving incoming requests. 1681 1811 */ … … 1711 1841 int ret; 1712 1842 int err; 1713 bool retry; 1843 int _count; 1844 bool ok, retry; 1714 1845 1715 1846 ret = readv(bsds->fd, state->vector, state->count); … … 1730 1861 state->ret += ret; 1731 1862 1732 while (ret > 0) { 1733 if (ret < state->vector[0].iov_len) { 1734 uint8_t *base; 1735 base = (uint8_t *)state->vector[0].iov_base; 1736 base += ret; 1737 state->vector[0].iov_base = (void *)base; 1738 state->vector[0].iov_len -= ret; 1739 break; 1740 } 1741 ret -= state->vector[0].iov_len; 1742 state->vector += 1; 1743 state->count -= 1; 1744 } 1745 1746 /* 1747 * there're maybe some empty vectors at the end 1748 * which we need to skip, otherwise we would get 1749 * ret == 0 from the readv() call and return EPIPE 1750 */ 1751 while (state->count > 0) { 1752 if (state->vector[0].iov_len > 0) { 1753 break; 1754 } 1755 state->vector += 1; 1756 state->count -= 1; 1863 _count = state->count; /* tstream has size_t count, readv has int */ 1864 ok = iov_advance(&state->vector, &_count, ret); 1865 state->count = _count; 1866 1867 if (!ok) { 1868 tevent_req_error(req, EINVAL); 1869 return; 1757 1870 } 1758 1871 … … 1871 1984 ssize_t ret; 1872 1985 int err; 1873 bool retry; 1986 int _count; 1987 bool ok, retry; 1874 1988 1875 1989 ret = writev(bsds->fd, state->vector, state->count); … … 1890 2004 state->ret += ret; 1891 2005 1892 while (ret > 0) { 1893 if (ret < state->vector[0].iov_len) { 1894 uint8_t *base; 1895 base = (uint8_t *)state->vector[0].iov_base; 1896 base += ret; 1897 state->vector[0].iov_base = (void *)base; 1898 state->vector[0].iov_len -= ret; 1899 break; 1900 } 1901 ret -= state->vector[0].iov_len; 1902 state->vector += 1; 1903 state->count -= 1; 1904 } 1905 1906 /* 1907 * there're maybe some empty vectors at the end 1908 * which we need to skip, otherwise we would get 1909 * ret == 0 from the writev() call and return EPIPE 1910 */ 1911 while (state->count > 0) { 1912 if (state->vector[0].iov_len > 0) { 1913 break; 1914 } 1915 state->vector += 1; 1916 state->count -= 1; 2006 _count = state->count; /* tstream has size_t count, writev has int */ 2007 ok = iov_advance(&state->vector, &_count, ret); 2008 state->count = _count; 2009 2010 if (!ok) { 2011 tevent_req_error(req, EINVAL); 2012 return; 1917 2013 } 1918 2014 … … 2079 2175 struct tsocket_address_bsd); 2080 2176 int ret; 2081 int err;2082 bool retry;2083 2177 bool do_bind = false; 2084 2178 bool do_reuseaddr = false; … … 2221 2315 2222 2316 ret = connect(state->fd, &rbsda->u.sa, rbsda->sa_socklen); 2223 err = tsocket_bsd_error_from_errno(ret, errno, &retry); 2224 if (retry) { 2225 /* retry later */ 2226 goto async; 2227 } 2228 if (tevent_req_error(req, err)) { 2317 if (ret == -1) { 2318 if (errno == EINPROGRESS) { 2319 goto async; 2320 } 2321 tevent_req_error(req, errno); 2229 2322 goto post; 2230 2323 } -
vendor/current/lib/tsocket/tsocket_guide.txt
r740 r988 3 3 ======================================= 4 4 5 The tsocket abstraction is split tedinto two5 The tsocket abstraction is split into two 6 6 different kinds of communitation interfaces. 7 7 8 There 's the "tstream_context" interface with abstracts8 There is the "tstream_context" interface which abstracts 9 9 the communication through a bidirectional 10 10 byte stream between two endpoints. 11 11 12 And there 's the "tdgram_context" interface13 w ith abstracts datagram based communication between any12 And there is the "tdgram_context" interface 13 which abstracts datagram based communication between any 14 14 number of endpoints. 15 15 … … 28 28 Constructors are described in later sections of this document. 29 29 30 A function get the string representation of an endpoint for debugging is30 A function to get the string representation of an endpoint for debugging is 31 31 available but callers SHOULD NOT try to parse this string. To get more 32 details callers should use getter methods of the specific tsocket_address32 details, callers should use getter methods of the specific tsocket_address 33 33 implemention. 34 34 … … 79 79 The tdgram_sendto_send() method can be called to send a 80 80 datagram (specified by a buf/len) to a destination endpoint 81 (specified by dst). It 's not allowed for len to be 0.81 (specified by dst). It is not allowed for len to be 0. 82 82 It returns a 'tevent_req' handle, where the caller can register a 83 83 callback with tevent_req_set_callback(). The callback is triggered … … 106 106 shutdown/close the abstracted socket. 107 107 108 The caller should make sure there 're no outstanding tdgram_recvfrom_send()108 The caller should make sure there are no outstanding tdgram_recvfrom_send() 109 109 and tdgram_sendto_send() calls otherwise the caller will get '*perrno = EBUSY'. 110 110 … … 137 137 of the given iovec vector. The caller has to preallocate the buffers 138 138 in the iovec vector. The caller might need to use 139 tstream_pending_bytes() if the protocol does n't have a fixed pdu header139 tstream_pending_bytes() if the protocol does not have a fixed pdu header 140 140 containing the pdu size. tstream_readv_send() returns a 'tevent_req' handle, 141 141 where the caller can register a callback with tevent_req_set_callback(). … … 146 146 tstream_readv_recv() on the 'tevent_req'. It returns -1 147 147 and sets '*perrno' to the actual 'errno' on failure. 148 Otherwise it returns the length of the datagram (0 is never returned!). 148 Otherwise it returns the total number of bytes received 149 (0 is never returned!). 149 150 150 151 The caller can only have one outstanding tstream_readv_send() … … 171 172 tstream_writev_recv() on the 'tevent_req'. It returns -1 172 173 and sets '*perrno' to the actual 'errno' on failure. 173 Otherwise it returns the total amount of bytes sent .174 Otherwise it returns the total amount of bytes sent 174 175 (0 is never returned!). 175 176 … … 189 190 shutdown/close the abstracted socket. 190 191 191 The caller should make sure there 're no outstanding tstream_readv_send()192 The caller should make sure there are no outstanding tstream_readv_send() 192 193 and tstream_writev_send() calls otherwise the caller will get '*perrno = EBUSY'. 193 194 … … 214 215 state for this function. The tstream_readv_pdu engine will ask 215 216 the next_vector function for the next iovec vector to be used. 216 There 's a tstream_readv_send/recv pair for each vector returned217 There is a tstream_readv_send/recv pair for each vector returned 217 218 by the next_vector function. If the next_vector function detects 218 219 it received a full pdu, it returns an empty vector. The the callback … … 241 242 =========================================== 242 243 243 In some cases the caller doesn't care about the IO ordering on the244 In some cases, the caller does not care about the IO ordering on the 244 245 abstracted socket. 245 (Remember at the low level there 's always only one IO in a specific246 (Remember at the low level there is always only one IO in a specific 246 247 direction allowed, only one tdgram_sendto_send() at a time). 247 248 … … 281 282 ================================ 282 283 283 The main tsocket library comes with imple ntations284 The main tsocket library comes with implementations 284 285 for BSD style ipv4, ipv6 and unix sockets. 285 286 … … 287 288 function to create a tsocket_address for ipv4 and ipv6 288 289 endpoint addresses. "family" can be "ipv4", "ipv6" or "ip". 289 With "ip" i sautodetects "ipv4" or "ipv6" based on the290 With "ip" it autodetects "ipv4" or "ipv6" based on the 290 291 "addr_string" string. "addr_string" must be a valid 291 292 ip address string based on the selected family 292 (dns names are not allowed!). But it 's valid to pass NULL,293 (dns names are not allowed!). But it is valid to pass NULL, 293 294 which gets mapped to "0.0.0.0" or "::". 294 295 It returns -1 and sets errno on error. Otherwise it returns 0. … … 303 304 you can use the tsocket_address_inet_addr_string() function. 304 305 It will return NULL and set errno to EINVAL if the tsocket_address 305 does n't represent an ipv4 or ipv6 endpoint address.306 does not represent an ipv4 or ipv6 endpoint address. 306 307 307 308 char *tsocket_address_inet_addr_string(const struct tsocket_address *addr, … … 311 312 you can use the tsocket_address_inet_port() function. 312 313 It will return 0 and set errno to EINVAL if the tsocket_address 313 does n't represent an ipv4 or ipv6 endpoint address.314 does not represent an ipv4 or ipv6 endpoint address. 314 315 315 316 uint16_t tsocket_address_inet_port(const struct tsocket_address *addr); … … 318 319 you can use the tsocket_address_inet_set_port() function. 319 320 It will return -1 and set errno to EINVAL if the tsocket_address 320 does n't represent an ipv4 or ipv6 endpoint address.321 does not represent an ipv4 or ipv6 endpoint address. 321 322 It returns 0 on success. 322 323 … … 336 337 struct tsocket_address **addr); 337 338 338 To get the path of a n'unix' tsocket_address339 To get the path of a 'unix' tsocket_address 339 340 you can use the tsocket_address_unix_path() function. 340 341 It will return NULL and set errno to EINVAL if the tsocket_address 341 does n't represent a unix domain endpoint path.342 does not represent a unix domain endpoint path. 342 343 343 344 char *tsocket_address_unix_path(const struct tsocket_address *addr, … … 431 432 struct tstream_context **stream2); 432 433 433 In some situations it's needed to create a tsocket_address from434 In some situations, it is needed to create a tsocket_address from 434 435 a given 'struct sockaddr'. You can use tsocket_address_bsd_from_sockaddr() 435 436 for that. This should only be used if really needed, because of … … 443 444 struct tsocket_address **addr); 444 445 445 In some situations it's needed to get a 'struct sockaddr' from a446 In some situations, it is needed to get a 'struct sockaddr' from a 446 447 given tsocket_address . You can use tsocket_address_bsd_sockaddr() 447 448 for that. This should only be used if really needed. Only AF_INET, … … 453 454 socklen_t sa_socklen); 454 455 455 In some situations it's needed to wrap existing file descriptors456 In some situations, it is needed to wrap existing file descriptors 456 457 into the tstream abstraction. You can use tstream_bsd_existing_socket() 457 458 for that. But you should read the tsocket_bsd.c code and unterstand it -
vendor/current/lib/tsocket/tsocket_helpers.c
r860 r988 53 53 struct tevent_req *req; 54 54 struct tdgram_sendto_queue_state *state; 55 bool ok;55 struct tevent_queue_entry *e; 56 56 57 57 req = tevent_req_create(mem_ctx, &state, … … 68 68 state->ret = -1; 69 69 70 ok = tevent_queue_add(queue, 71 ev, 72 req, 73 tdgram_sendto_queue_trigger, 74 NULL); 75 if (!ok) { 76 tevent_req_nomem(NULL, req); 77 goto post; 78 } 79 80 return req; 81 82 post: 83 tevent_req_post(req, ev); 70 /* 71 * we use tevent_queue_add_optimize_empty() with allow_direct 72 * in order to optimize for the empty queue case. 73 */ 74 e = tevent_queue_add_optimize_empty( 75 queue, 76 ev, 77 req, 78 tdgram_sendto_queue_trigger, 79 NULL); 80 if (tevent_req_nomem(e, req)) { 81 return tevent_req_post(req, ev); 82 } 83 if (!tevent_req_is_in_progress(req)) { 84 return tevent_req_post(req, ev); 85 } 86 84 87 return req; 85 88 } … … 356 359 struct tevent_req *req; 357 360 struct tstream_readv_pdu_queue_state *state; 358 bool ok;361 struct tevent_queue_entry *e; 359 362 360 363 req = tevent_req_create(mem_ctx, &state, … … 370 373 state->ret = -1; 371 374 372 ok = tevent_queue_add(queue, 373 ev, 374 req, 375 tstream_readv_pdu_queue_trigger, 376 NULL); 377 if (!ok) { 378 tevent_req_nomem(NULL, req); 379 goto post; 375 /* 376 * we use tevent_queue_add_optimize_empty() with allow_direct 377 * in order to optimize for the empty queue case. 378 */ 379 e = tevent_queue_add_optimize_empty( 380 queue, 381 ev, 382 req, 383 tstream_readv_pdu_queue_trigger, 384 NULL); 385 if (tevent_req_nomem(e, req)) { 386 return tevent_req_post(req, ev); 387 } 388 if (!tevent_req_is_in_progress(req)) { 389 return tevent_req_post(req, ev); 380 390 } 381 391 382 392 return req; 383 384 post:385 return tevent_req_post(req, ev);386 393 } 387 394 … … 463 470 struct tevent_req *req; 464 471 struct tstream_writev_queue_state *state; 465 bool ok;472 struct tevent_queue_entry *e; 466 473 467 474 req = tevent_req_create(mem_ctx, &state, … … 477 484 state->ret = -1; 478 485 479 ok = tevent_queue_add(queue, 480 ev, 481 req, 482 tstream_writev_queue_trigger, 483 NULL); 484 if (!ok) { 485 tevent_req_nomem(NULL, req); 486 goto post; 486 /* 487 * we use tevent_queue_add_optimize_empty() with allow_direct 488 * in order to optimize for the empty queue case. 489 */ 490 e = tevent_queue_add_optimize_empty( 491 queue, 492 ev, 493 req, 494 tstream_writev_queue_trigger, 495 NULL); 496 if (tevent_req_nomem(e, req)) { 497 return tevent_req_post(req, ev); 498 } 499 if (!tevent_req_is_in_progress(req)) { 500 return tevent_req_post(req, ev); 487 501 } 488 502 489 503 return req; 490 491 post:492 return tevent_req_post(req, ev);493 504 } 494 505 -
vendor/current/lib/tsocket/wscript_build
r740 r988 4 4 bld.SAMBA_SUBSYSTEM('LIBTSOCKET', 5 5 source='tsocket.c tsocket_helpers.c tsocket_bsd.c', 6 public_deps='talloc tevent ',6 public_deps='talloc tevent iov_buf socket-blocking', 7 7 public_headers='tsocket.h tsocket_internal.h', 8 8 )
Note:
See TracChangeset
for help on using the changeset viewer.