Overview
Comment: | Use OFData instead of a buffer for async UDP sends
This avoids the entire problem of keeping the buffer alive until the |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
0f3ae90eef3c48fb8b7dd1ac8a7abf06 |
User & Date: | js on 2018-12-18 21:17:28 |
Other Links: | manifest | tags |
Context
2018-12-21
| ||
21:39 | Remove context from OFHTTPClientDelegate check-in: eaf458c1e6 user: js tags: trunk | |
2018-12-18
| ||
21:17 | Use OFData instead of a buffer for async UDP sends check-in: 0f3ae90eef user: js tags: trunk | |
17:14 | OFHTTPClient: Fix type mismatch check-in: 9036359e2e user: js tags: trunk | |
Changes
Modified src/OFDNSResolver.m from [15c765674a] to [411a1eb381].
︙ | ︙ | |||
1808 1809 1810 1811 1812 1813 1814 | sock = _IPv4Socket; break; default: @throw [OFInvalidArgumentException exception]; } | < | | | | 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 | sock = _IPv4Socket; break; default: @throw [OFInvalidArgumentException exception]; } [sock asyncSendData: query->_queryData receiver: &query->_usedNameServer runLoopMode: runLoopMode]; } - (void)of_queryWithIDTimedOut: (OFDNSResolverQuery *)query { OFResolveHostFailedException *exception; if (query == nil) |
︙ | ︙ | |||
1866 1867 1868 1869 1870 1871 1872 | callback(query->_target, query->_selector, self, query->_domainName, nil, nil, nil, query->_context, exception); } - (bool)socket: (OF_KINDOF(OFUDPSocket *))sock didReceiveIntoBuffer: (void *)buffer_ length: (size_t)length | | | 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 | callback(query->_target, query->_selector, self, query->_domainName, nil, nil, nil, query->_context, exception); } - (bool)socket: (OF_KINDOF(OFUDPSocket *))sock didReceiveIntoBuffer: (void *)buffer_ length: (size_t)length sender: (const of_socket_address_t *)sender exception: (id)exception { unsigned char *buffer = buffer_; OFDictionary *answerRecords = nil, *authorityRecords = nil; OFDictionary *additionalRecords = nil; OFNumber *ID; OFDNSResolverQuery *query; |
︙ | ︙ | |||
1888 1889 1890 1891 1892 1893 1894 | ID = [OFNumber numberWithUInt16: (buffer[0] << 8) | buffer[1]]; query = [[[_queries objectForKey: ID] retain] autorelease]; if (query == nil) return true; | | | 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 | ID = [OFNumber numberWithUInt16: (buffer[0] << 8) | buffer[1]]; query = [[[_queries objectForKey: ID] retain] autorelease]; if (query == nil) return true; if (!of_socket_address_equal(sender, &query->_usedNameServer)) return true; [query->_cancelTimer invalidate]; [query->_cancelTimer release]; query->_cancelTimer = nil; [_queries removeObjectForKey: ID]; |
︙ | ︙ |
Modified src/OFRunLoop+Private.h from [55f8a4342c] to [ce02ac66ef].
︙ | ︙ | |||
105 106 107 108 109 110 111 | block: (nullable of_udp_socket_async_receive_block_t) block # endif delegate: (nullable id <OFUDPSocketDelegate>) delegate; + (void)of_addAsyncSendForUDPSocket: (OFUDPSocket *)socket | < | | | > | 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 | block: (nullable of_udp_socket_async_receive_block_t) block # endif delegate: (nullable id <OFUDPSocketDelegate>) delegate; + (void)of_addAsyncSendForUDPSocket: (OFUDPSocket *)socket data: (OFData *)data receiver: (const of_socket_address_t *)receiver mode: (of_run_loop_mode_t)mode # ifdef OF_HAVE_BLOCKS block: (nullable of_udp_socket_async_send_data_block_t) block # endif delegate: (nullable id <OFUDPSocketDelegate>) delegate; + (void)of_cancelAsyncRequestsForObject: (id)object mode: (of_run_loop_mode_t)mode; #endif - (void)of_removeTimer: (OFTimer *)timer forMode: (of_run_loop_mode_t)mode; @end OF_ASSUME_NONNULL_END |
Modified src/OFRunLoop.m from [8d0f224f35] to [6ee3abdf2e].
︙ | ︙ | |||
159 160 161 162 163 164 165 | } @end @interface OFRunLoop_UDPSendQueueItem: OFRunLoop_QueueItem { @public # ifdef OF_HAVE_BLOCKS | | | < | 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | } @end @interface OFRunLoop_UDPSendQueueItem: OFRunLoop_QueueItem { @public # ifdef OF_HAVE_BLOCKS of_udp_socket_async_send_data_block_t _block; # endif OFData *_data; of_socket_address_t _receiver; } @end #endif @implementation OFRunLoop_State - (instancetype)init |
︙ | ︙ | |||
679 680 681 682 683 684 685 | } @catch (id e) { length = 0; exception = e; } # ifdef OF_HAVE_BLOCKS if (_block != NULL) | | | > | | | | > > > > > > | | | | < > > > > > > > | < > > > < | 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 | } @catch (id e) { length = 0; exception = e; } # ifdef OF_HAVE_BLOCKS if (_block != NULL) return _block(object, _buffer, length, &address, exception); else { # endif if (![_delegate respondsToSelector: @selector( socket:didReceiveIntoBuffer:length:sender:exception:)]) return false; return [_delegate socket: object didReceiveIntoBuffer: _buffer length: length sender: &address exception: exception]; # ifdef OF_HAVE_BLOCKS } # endif } # ifdef OF_HAVE_BLOCKS - (void)dealloc { [_block release]; [super dealloc]; } # endif @end @implementation OFRunLoop_UDPSendQueueItem - (bool)handleObject: (id)object { id exception = nil; OFData *newData, *oldData; @try { [object sendBuffer: [_data items] length: [_data count] * [_data itemSize] receiver: &_receiver]; } @catch (id e) { exception = e; } # ifdef OF_HAVE_BLOCKS if (_block != NULL) { newData = _block(object, _data, &_receiver, exception); if (newData == nil) return false; oldData = _data; _data = [newData copy]; [oldData release]; return true; } else { # endif if (![_delegate respondsToSelector: @selector(socket:didSendData:receiver:exception:)]) return false; newData = [_delegate socket: object didSendData: _data receiver: &_receiver exception: exception]; if (newData == nil) return false; oldData = _data; _data = [newData copy]; [oldData release]; return true; # ifdef OF_HAVE_BLOCKS } # endif } - (void)dealloc { [_data release]; # ifdef OF_HAVE_BLOCKS [_block release]; # endif [super dealloc]; } @end #endif @implementation OFRunLoop @synthesize currentMode = _currentMode; + (OFRunLoop *)mainRunLoop |
︙ | ︙ | |||
978 979 980 981 982 983 984 | queueItem->_buffer = buffer; queueItem->_length = length; QUEUE_ITEM } + (void)of_addAsyncSendForUDPSocket: (OFUDPSocket *)sock | < | | | > | < | | 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 | queueItem->_buffer = buffer; queueItem->_length = length; QUEUE_ITEM } + (void)of_addAsyncSendForUDPSocket: (OFUDPSocket *)sock data: (OFData *)data receiver: (const of_socket_address_t *)receiver mode: (of_run_loop_mode_t)mode # ifdef OF_HAVE_BLOCKS block: (of_udp_socket_async_send_data_block_t) block # endif delegate: (id <OFUDPSocketDelegate>)delegate { NEW_WRITE(OFRunLoop_UDPSendQueueItem, sock, mode) queueItem->_delegate = [delegate retain]; # ifdef OF_HAVE_BLOCKS queueItem->_block = [block copy]; # endif queueItem->_data = [data copy]; queueItem->_receiver = *receiver; QUEUE_ITEM } # undef NEW_READ # undef NEW_WRITE # undef QUEUE_ITEM |
︙ | ︙ |
Modified src/OFStream.h from [b1f1d40d96] to [123c708db9].
︙ | ︙ | |||
46 47 48 49 50 51 52 | * @param stream The stream on which data was read * @param buffer A buffer with the data that has been read * @param length The length of the data that has been read * @param exception An exception which occurred while reading or `nil` on * success * @return A bool whether the same block should be used for the next read */ | | > | | > | | | | | 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | * @param stream The stream on which data was read * @param buffer A buffer with the data that has been read * @param length The length of the data that has been read * @param exception An exception which occurred while reading or `nil` on * success * @return A bool whether the same block should be used for the next read */ typedef bool (^of_stream_async_read_block_t)( OF_KINDOF(OFStream *) _Nonnull stream, void *_Nonnull buffer, size_t length, id _Nullable exception); /*! * @brief A block which is called when a line was read asynchronously from a * stream. * * @param stream The stream on which a line was read * @param line The line which has been read or `nil` when the end of stream * occurred * @param exception An exception which occurred while reading or `nil` on * success * @return A bool whether the same block should be used for the next read */ typedef bool (^of_stream_async_read_line_block_t)( OF_KINDOF(OFStream *) _Nonnull stream, OFString *_Nullable line, id _Nullable exception); /*! * @brief A block which is called when data was written asynchronously to a * stream. * * @param data The data which was written to the stream * @param bytesWritten The number of bytes which have been written. This * matches the length of the specified data on the * asynchronous write if no exception was encountered. * @param exception An exception which occurred while writing or `nil` on * success * @return The data to repeat the write with or nil if it should not repeat */ typedef OFData *_Nullable (^of_stream_async_write_data_block_t)( OF_KINDOF(OFStream *) _Nonnull stream, OFData *_Nonnull data, size_t bytesWritten, id _Nullable exception); /*! * @brief A block which is called when a string was written asynchronously to a * stream. * * @param string The string which was written to the stream * @param bytesWritten The number of bytes which have been written. This * matches the length of the specified data on the * asynchronous write if no exception was encountered. * @param encoding The encoding in which the string was written * @param exception An exception which occurred while writing or `nil` on * success * @return The string to repeat the write with or nil if it should not repeat */ typedef OFString *_Nullable (^of_stream_async_write_string_block_t)( OF_KINDOF(OFStream *) _Nonnull stream, OFString *_Nonnull string, of_string_encoding_t encoding, size_t bytesWritten, id _Nullable exception); #endif /*! * @protocol OFStreamDelegate OFStream.h ObjFW/OFStream.h * * A delegate for OFStream. |
︙ | ︙ |
Modified src/OFUDPSocket.h from [ab6554e3b4] to [9eef6bdbf0].
︙ | ︙ | |||
35 36 37 38 39 40 41 | * @param buffer The buffer the packet has been written to * @param length The length of the packet * @param sender The address of the sender of the packet * @param exception An exception which occurred while receiving or `nil` on * success * @return A bool whether the same block should be used for the next receive */ | | | | | < < < < | < | < < < | | | | 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 | * @param buffer The buffer the packet has been written to * @param length The length of the packet * @param sender The address of the sender of the packet * @param exception An exception which occurred while receiving or `nil` on * success * @return A bool whether the same block should be used for the next receive */ typedef bool (^of_udp_socket_async_receive_block_t)( OFUDPSocket *_Nonnull socket, void *_Nonnull buffer, size_t length, const of_socket_address_t *_Nonnull sender, id _Nullable exception); /*! * @brief A block which is called when a packet has been sent. * * @param socket The UDP socket which sent a packet * @param data The data which was sent * @param receiver The receiver for the UDP packet * @param exception An exception which occurred while reading or `nil` on * success * @return The data to repeat the send with or nil if it should not repeat */ typedef OFData *_Nullable (^of_udp_socket_async_send_data_block_t)( OFUDPSocket *_Nonnull socket, OFData *_Nonnull data, const of_socket_address_t *_Nonnull receiver, id _Nullable exception); #endif /*! * @protocol OFUDPSocketDelegate OFUDPSocket.h ObjFW/OFUDPSocket.h * * @brief A delegate for OFUDPSocket. */ |
︙ | ︙ | |||
83 84 85 86 87 88 89 | * @param exception An exception that occurred while receiving, or nil on * success * @return A bool whether the same block should be used for the next receive */ - (bool)socket: (OF_KINDOF(OFUDPSocket *))socket didReceiveIntoBuffer: (void *)buffer length: (size_t)length | | | < < | < | < < < | | < | | | 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 | * @param exception An exception that occurred while receiving, or nil on * success * @return A bool whether the same block should be used for the next receive */ - (bool)socket: (OF_KINDOF(OFUDPSocket *))socket didReceiveIntoBuffer: (void *)buffer length: (size_t)length sender: (const of_socket_address_t *_Nonnull)sender exception: (nullable id)exception; /*! * @brief This which is called when a packet has been sent. * * @param socket The UDP socket which sent a packet * @param data The data which was sent * @param receiver The receiver for the UDP packet * @param exception An exception that occurred while sending, or nil on success * @return The data to repeat the send with or nil if it should not repeat */ - (nullable OFData *)socket: (OF_KINDOF(OFUDPSocket *))socket didSendData: (OFData *)data receiver: (const of_socket_address_t *_Nonnull)receiver exception: (nullable id)exception; @end /*! * @class OFUDPSocket OFUDPSocket.h ObjFW/OFUDPSocket.h * * @brief A class which provides methods to create and use UDP sockets. * |
︙ | ︙ | |||
271 272 273 274 275 276 277 | - (void)sendBuffer: (const void *)buffer length: (size_t)length receiver: (const of_socket_address_t *)receiver; /*! * @brief Asynchronously sends the specified datagram to the specified address. * | | < | | < | | < | | < | | | < | | | < < | < | | | < | | | < < | < | | | | 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 | - (void)sendBuffer: (const void *)buffer length: (size_t)length receiver: (const of_socket_address_t *)receiver; /*! * @brief Asynchronously sends the specified datagram to the specified address. * * @param data The data to send as a datagram * @param receiver A pointer to an @ref of_socket_address_t to which the * datagram should be sent. The receiver is copied. */ - (void)asyncSendData: (OFData *)data receiver: (const of_socket_address_t *)receiver; /*! * @brief Asynchronously sends the specified datagram to the specified address. * * @param data The data to send as a datagram * @param receiver A pointer to an @ref of_socket_address_t to which the * datagram should be sent. The receiver is copied. * @param runLoopMode The run loop mode in which to perform the async send */ - (void)asyncSendData: (OFData *)data receiver: (const of_socket_address_t *)receiver runLoopMode: (of_run_loop_mode_t)runLoopMode; #ifdef OF_HAVE_BLOCKS /*! * @brief Asynchronously sends the specified datagram to the specified address. * * @param data The data to send as a datagram * @param receiver A pointer to an @ref of_socket_address_t to which the * datagram should be sent. The receiver is copied. * @param block The block to call when the packet has been sent. It should * return the data for the next send with the same callback or nil * if it should not repeat. */ - (void)asyncSendData: (OFData *)data receiver: (const of_socket_address_t *)receiver block: (of_udp_socket_async_send_data_block_t)block; /*! * @brief Asynchronously sends the specified datagram to the specified address. * * @param data The data to send as a datagram * @param receiver A pointer to an @ref of_socket_address_t to which the * datagram should be sent. The receiver is copied. * @param runLoopMode The run loop mode in which to perform the async send * @param block The block to call when the packet has been sent. It should * return the data for the next send with the same callback or nil * if it should not repeat. */ - (void)asyncSendData: (OFData *)data receiver: (const of_socket_address_t *)receiver runLoopMode: (of_run_loop_mode_t)runLoopMode block: (of_udp_socket_async_send_data_block_t)block; #endif /*! * @brief Cancels all pending asynchronous requests on the socket. */ - (void)cancelAsyncRequests; |
︙ | ︙ |
Modified src/OFUDPSocket.m from [9559b91b20] to [83f1dff89c].
︙ | ︙ | |||
412 413 414 415 416 417 418 | if ((size_t)bytesWritten != length) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length bytesWritten: bytesWritten errNo: 0]; } | | < | | < | | | < | | | < | < | | | < | | | | < | | | | < | 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 | if ((size_t)bytesWritten != length) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length bytesWritten: bytesWritten errNo: 0]; } - (void)asyncSendData: (OFData *)data receiver: (const of_socket_address_t *)receiver { [self asyncSendData: data receiver: receiver runLoopMode: of_run_loop_mode_default]; } - (void)asyncSendData: (OFData *)data receiver: (const of_socket_address_t *)receiver runLoopMode: (of_run_loop_mode_t)runLoopMode { [OFRunLoop of_addAsyncSendForUDPSocket: self data: data receiver: receiver mode: runLoopMode # ifdef OF_HAVE_BLOCKS block: NULL # endif delegate: _delegate]; } #ifdef OF_HAVE_BLOCKS - (void)asyncSendData: (OFData *)data receiver: (const of_socket_address_t *)receiver block: (of_udp_socket_async_send_data_block_t)block { [self asyncSendData: data receiver: receiver runLoopMode: of_run_loop_mode_default block: block]; } - (void)asyncSendData: (OFData *)data receiver: (const of_socket_address_t *)receiver runLoopMode: (of_run_loop_mode_t)runLoopMode block: (of_udp_socket_async_send_data_block_t)block { [OFRunLoop of_addAsyncSendForUDPSocket: self data: data receiver: receiver mode: runLoopMode block: block delegate: nil]; } #endif |
︙ | ︙ |
Modified src/socket.h from [949bb8ad8d] to [0d7cd9ede1].
︙ | ︙ | |||
172 173 174 175 176 177 178 | /*! * @brief Compares two of_socket_address_t for equality. * * @param address1 The address to compare with the second address * @param address2 The second address * @return Whether the two addresses are equal */ | | | > | > | 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | /*! * @brief Compares two of_socket_address_t for equality. * * @param address1 The address to compare with the second address * @param address2 The second address * @return Whether the two addresses are equal */ extern bool of_socket_address_equal( const of_socket_address_t *_Nonnull address1, const of_socket_address_t *_Nonnull address2); /*! * @brief Returns the hash for the specified of_socket_address_t. * * @param address The address to hash * @return The hash for the specified of_socket_address_t */ extern uint32_t of_socket_address_hash( const of_socket_address_t *_Nonnull address); /*! * @brief Converts the specified of_socket_address_t to an IP string and port. * * @param address The address to convert to a string * @param port A pointer to an uint16_t which should be set to the port of the * address or NULL if the port is not needed |
︙ | ︙ |
Modified src/socket.m from [fd66b3751b] to [b9d1cba50d].
︙ | ︙ | |||
390 391 392 393 394 395 396 | return of_socket_address_parse_ipv6(IP, port); } @catch (OFInvalidFormatException *e) { return of_socket_address_parse_ipv4(IP, port); } } bool | | | | | | 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 | return of_socket_address_parse_ipv6(IP, port); } @catch (OFInvalidFormatException *e) { return of_socket_address_parse_ipv4(IP, port); } } bool of_socket_address_equal(const of_socket_address_t *address1, const of_socket_address_t *address2) { const struct sockaddr_in *addrIn1, *addrIn2; const struct sockaddr_in6 *addrIn6_1, *addrIn6_2; if (address1->family != address2->family) return false; switch (address1->family) { case OF_SOCKET_ADDRESS_FAMILY_IPV4: #ifndef OF_WII |
︙ | ︙ | |||
443 444 445 446 447 448 449 | @throw [OFInvalidArgumentException exception]; } return true; } uint32_t | | | 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 | @throw [OFInvalidArgumentException exception]; } return true; } uint32_t of_socket_address_hash(const of_socket_address_t *address) { uint32_t hash; OF_HASH_INIT(hash); OF_HASH_ADD(hash, address->family); switch (address->family) { |
︙ | ︙ |