Overview
Comment: | OFUDPSocket: Add support for async sending |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
842c55dd83aa0d12786d68e37cbb5c24 |
User & Date: | js on 2017-09-24 17:35:04 |
Other Links: | manifest | tags |
Context
2017-09-24
| ||
21:00 | OFHTTPClient: Rename to -[asyncPerformRequest:] check-in: 0319fe1eb9 user: js tags: trunk | |
17:35 | OFUDPSocket: Add support for async sending check-in: 842c55dd83 user: js tags: trunk | |
16:34 | Minor documentation fix check-in: a0394db776 user: js tags: trunk | |
Changes
Modified src/OFHTTPClient.m from [bea7b309df] to [390eee68b1].
︙ | ︙ | |||
522 523 524 525 526 527 528 529 530 531 532 533 534 535 | - (size_t)socket: (OFTCPSocket *)socket didWriteBody: (const void **)body length: (size_t)length context: (id)context exception: (id)exception { [socket asyncReadLineWithTarget: self selector: @selector(socket:didReadLine:context: exception:) context: nil]; return 0; } | > > > > > > > | 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 | - (size_t)socket: (OFTCPSocket *)socket didWriteBody: (const void **)body length: (size_t)length context: (id)context exception: (id)exception { if (exception != nil) { [_client->_delegate client: _client didEncounterException: exception forRequest: _request]; return 0; } [socket asyncReadLineWithTarget: self selector: @selector(socket:didReadLine:context: exception:) context: nil]; return 0; } |
︙ | ︙ | |||
549 550 551 552 553 554 555 | [self closeAndReconnect]; return false; } [_client->_delegate client: _client didEncounterException: exception forRequest: _request]; | | | 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 | [self closeAndReconnect]; return false; } [_client->_delegate client: _client didEncounterException: exception forRequest: _request]; return 0; } if ((body = [_request body]) != nil) { [socket asyncWriteBuffer: [body items] length: [body count] * [body itemSize] target: self selector: @selector(socket:didWriteBody:length: |
︙ | ︙ |
Modified src/OFRunLoop+Private.h from [9ea44e6f29] to [f6fcbe1db8].
︙ | ︙ | |||
54 55 56 57 58 59 60 61 62 63 64 65 66 67 | context: (nullable id)context; + (void)of_addAsyncReceiveForUDPSocket: (OFUDPSocket *)socket buffer: (void *)buffer length: (size_t)length target: (id)target selector: (SEL)selector context: (nullable id)context; # ifdef OF_HAVE_BLOCKS + (void)of_addAsyncReadForStream: (OFStream *)stream buffer: (void *)buffer length: (size_t)length block: (of_stream_async_read_block_t)block; + (void)of_addAsyncReadForStream: (OFStream *)stream buffer: (void *)buffer | > > > > > > > | 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | context: (nullable id)context; + (void)of_addAsyncReceiveForUDPSocket: (OFUDPSocket *)socket buffer: (void *)buffer length: (size_t)length target: (id)target selector: (SEL)selector context: (nullable id)context; + (void)of_addAsyncSendForUDPSocket: (OFUDPSocket *)socket buffer: (const void *)buffer length: (size_t)length receiver: (of_udp_socket_address_t)receiver target: (id)target selector: (SEL)selector context: (nullable id)context; # ifdef OF_HAVE_BLOCKS + (void)of_addAsyncReadForStream: (OFStream *)stream buffer: (void *)buffer length: (size_t)length block: (of_stream_async_read_block_t)block; + (void)of_addAsyncReadForStream: (OFStream *)stream buffer: (void *)buffer |
︙ | ︙ | |||
78 79 80 81 82 83 84 85 86 87 88 89 90 91 | block: (of_tcp_socket_async_accept_block_t) block; + (void)of_addAsyncReceiveForUDPSocket: (OFUDPSocket *)socket buffer: (void *)buffer length: (size_t)length block: (of_udp_socket_async_receive_block_t) block; # endif + (void)of_cancelAsyncRequestsForObject: (id)object; #endif - (void)of_removeTimer: (OFTimer *)timer; @end OF_ASSUME_NONNULL_END | > > > > > | 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | block: (of_tcp_socket_async_accept_block_t) block; + (void)of_addAsyncReceiveForUDPSocket: (OFUDPSocket *)socket buffer: (void *)buffer length: (size_t)length block: (of_udp_socket_async_receive_block_t) block; + (void)of_addAsyncSendForUDPSocket: (OFUDPSocket *)socket buffer: (const void *)buffer length: (size_t)length receiver: (of_udp_socket_address_t)receiver block: (of_udp_socket_async_send_block_t)block; # endif + (void)of_cancelAsyncRequestsForObject: (id)object; #endif - (void)of_removeTimer: (OFTimer *)timer; @end OF_ASSUME_NONNULL_END |
Modified src/OFRunLoop.m from [fbe3b55d16] to [2cf7056bd3].
︙ | ︙ | |||
109 110 111 112 113 114 115 116 117 118 119 120 121 122 | # ifdef OF_HAVE_BLOCKS of_udp_socket_async_receive_block_t _block; # endif void *_buffer; size_t _length; } @end @implementation OFRunLoop_QueueItem - (bool)handleObject: (id)object { OF_UNRECOGNIZED_SELECTOR } | > > > > > > > > > > > > | 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 | # ifdef OF_HAVE_BLOCKS of_udp_socket_async_receive_block_t _block; # endif void *_buffer; size_t _length; } @end @interface OFRunLoop_UDPSendQueueItem: OFRunLoop_QueueItem { @public # ifdef OF_HAVE_BLOCKS of_udp_socket_async_send_block_t _block; # endif const void *_buffer; size_t _length; of_udp_socket_address_t _receiver; } @end @implementation OFRunLoop_QueueItem - (bool)handleObject: (id)object { OF_UNRECOGNIZED_SELECTOR } |
︙ | ︙ | |||
379 380 381 382 383 384 385 | # ifdef OF_HAVE_BLOCKS if (_block != NULL) return _block(object, _buffer, length, address, exception); else { # endif bool (*func)(id, SEL, OFUDPSocket *, void *, size_t, | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 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 | # ifdef OF_HAVE_BLOCKS if (_block != NULL) return _block(object, _buffer, length, address, exception); else { # endif bool (*func)(id, SEL, OFUDPSocket *, void *, size_t, of_udp_socket_address_t, id, id) = (bool (*)(id, SEL, OFUDPSocket *, void *, size_t, of_udp_socket_address_t, id, id)) [_target methodForSelector: _selector]; return func(_target, _selector, object, _buffer, length, address, _context, 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; @try { [object sendBuffer: _buffer length: _length receiver: &_receiver]; } @catch (id e) { exception = e; } # ifdef OF_HAVE_BLOCKS if (_block != NULL) { _length = _block(object, &_buffer, (exception == nil ? _length : 0), &_receiver, exception); return (_length > 0); } else { # endif size_t (*func)(id, SEL, OFUDPSocket *, const void *, size_t, of_udp_socket_address_t *, id, id) = (size_t (*)(id, SEL, OFUDPSocket *, const void *, size_t, of_udp_socket_address_t *, id, id)) [_target methodForSelector: _selector]; _length = func(_target, _selector, object, &_buffer, (exception == nil ? _length : 0), &_receiver, _context, exception); return (_length > 0); # ifdef OF_HAVE_BLOCKS } # endif } # ifdef OF_HAVE_BLOCKS - (void)dealloc { [_block release]; [super dealloc]; |
︙ | ︙ | |||
555 556 557 558 559 560 561 562 563 564 565 566 567 568 | queueItem->_target = [target retain]; queueItem->_selector = selector; queueItem->_context = [context retain]; queueItem->_buffer = buffer; queueItem->_length = length; }) } # ifdef OF_HAVE_BLOCKS + (void)of_addAsyncReadForStream: (OFStream *)stream buffer: (void *)buffer length: (size_t)length block: (of_stream_async_read_block_t)block { | > > > > > > > > > > > > > > > > > > | 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 | queueItem->_target = [target retain]; queueItem->_selector = selector; queueItem->_context = [context retain]; queueItem->_buffer = buffer; queueItem->_length = length; }) } + (void)of_addAsyncSendForUDPSocket: (OFUDPSocket *)socket buffer: (const void *)buffer length: (size_t)length receiver: (of_udp_socket_address_t)receiver target: (id)target selector: (SEL)selector context: (id)context { ADD_WRITE(OFRunLoop_UDPSendQueueItem, socket, { queueItem->_target = [target retain]; queueItem->_selector = selector; queueItem->_context = [context retain]; queueItem->_buffer = buffer; queueItem->_length = length; queueItem->_receiver = receiver; }) } # ifdef OF_HAVE_BLOCKS + (void)of_addAsyncReadForStream: (OFStream *)stream buffer: (void *)buffer length: (size_t)length block: (of_stream_async_read_block_t)block { |
︙ | ︙ | |||
618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 | + (void)of_addAsyncReceiveForUDPSocket: (OFUDPSocket *)socket buffer: (void *)buffer length: (size_t)length block: (of_udp_socket_async_receive_block_t) block { ADD_READ(OFRunLoop_UDPReceiveQueueItem, socket, { queueItem->_buffer = buffer; queueItem->_length = length; queueItem->_block = [block copy]; }) } # endif # undef ADD_READ # undef ADD_WRITE + (void)of_cancelAsyncRequestsForObject: (id)object | > > > > > > > > > > > > > > | 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 | + (void)of_addAsyncReceiveForUDPSocket: (OFUDPSocket *)socket buffer: (void *)buffer length: (size_t)length block: (of_udp_socket_async_receive_block_t) block { ADD_READ(OFRunLoop_UDPReceiveQueueItem, socket, { queueItem->_block = [block copy]; queueItem->_buffer = buffer; queueItem->_length = length; }) } + (void)of_addAsyncSendForUDPSocket: (OFUDPSocket *)socket buffer: (const void *)buffer length: (size_t)length receiver: (of_udp_socket_address_t)receiver block: (of_udp_socket_async_send_block_t)block { ADD_WRITE(OFRunLoop_UDPSendQueueItem, socket, { queueItem->_block = [block copy]; queueItem->_buffer = buffer; queueItem->_length = length; queueItem->_receiver = receiver; }) } # endif # undef ADD_READ # undef ADD_WRITE + (void)of_cancelAsyncRequestsForObject: (id)object |
︙ | ︙ |
Modified src/OFStream.h from [62644beb20] to [66d00ee4d4].
︙ | ︙ | |||
63 64 65 66 67 68 69 | typedef bool (^of_stream_async_read_line_block_t)(OFStream *stream, OFString *_Nullable line, id _Nullable exception); /*! * @brief A block which is called when data was written to the stream. * * @param stream The stream to which data was written | | > > | | 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | typedef bool (^of_stream_async_read_line_block_t)(OFStream *stream, OFString *_Nullable line, id _Nullable exception); /*! * @brief A block which is called when data was written to the stream. * * @param stream The stream to which data was written * @param buffer A pointer to the buffer which was written to the stream. This * can be changed to point to a different buffer to be used on the * next write. * @param bytesWritten The number of bytes which have been written. This * matches the length specified on the asynchronous write * if no exception was encountered. * @param exception An exception which occurred while writing or `nil` on * success * @return The length to repeat the write with or 0 if it should not repeat. * The buffer may be changed, so that every time a new buffer and length * can be specified while the callback stays the same. */ typedef size_t (^of_stream_async_write_block_t)(OFStream *stream, const void *_Nonnull *_Nonnull buffer, size_t bytesWritten, |
︙ | ︙ | |||
817 818 819 820 821 822 823 | * @param target The target on which the selector should be called when the * data has been written. The method should return the length for * the next write with the same callback or 0 if it should not * repeat. The buffer may be changed, so that every time a new * buffer and length can be specified while the callback stays * the same. * @param selector The selector to call on the target. The signature must be | | | 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 | * @param target The target on which the selector should be called when the * data has been written. The method should return the length for * the next write with the same callback or 0 if it should not * repeat. The buffer may be changed, so that every time a new * buffer and length can be specified while the callback stays * the same. * @param selector The selector to call on the target. The signature must be * `size_t (OFStream *stream, const void *buffer, * size_t bytesWritten, id context, id exception)`. * @param context A context object to pass along to the target */ - (void)asyncWriteBuffer: (const void *)buffer length: (size_t)length target: (id)target selector: (SEL)selector |
︙ | ︙ |
Modified src/OFUDPSocket.h from [dca0ed119a] to [c400113946].
︙ | ︙ | |||
48 49 50 51 52 53 54 | */ typedef void (^of_udp_socket_async_resolve_block_t)(OFString *host, uint16_t port, of_udp_socket_address_t address, id _Nullable exception); /*! * @brief A block which is called when a packet has been received. * | | > > > > > > > > > > > > > > > > > > > > > > | 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 | */ typedef void (^of_udp_socket_async_resolve_block_t)(OFString *host, uint16_t port, of_udp_socket_address_t address, id _Nullable exception); /*! * @brief A block which is called when a packet has been received. * * @param socket The UDP socket which received a packet * @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 *socket, void *buffer, size_t length, of_udp_socket_address_t 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 buffer A pointer to the buffer which was sent. This can be changed to * point to a different buffer to be used on the next send. * @param bytesSent The number of bytes which have been sent. This matches the * length specified on the asynchronous send if no exception * was encountered. * @param receiver The receiver for the UDP packet. This may be set to a new * receiver to which the next packet is sent. * @param exception An exception which occurred while reading or `nil` on * success * @return The length to repeat the send with or 0 if it should not repeat. * The buffer and receiver may be changed, so that every time a new * buffer, length and receiver can be specified while the callback * stays the same. */ typedef size_t (^of_udp_socket_async_send_block_t)(OFUDPSocket *socket, const void *_Nonnull *_Nonnull buffer, size_t bytesSent, of_udp_socket_address_t *_Nonnull receiver, id exception); #endif /*! * @class OFUDPSocket OFUDPSocket.h ObjFW/OFUDPSocket.h * * @brief A class which provides methods to create and use UDP sockets. * |
︙ | ︙ | |||
201 202 203 204 205 206 207 | * datagram has been received. If the method returns true, it * will be called again with the same buffer and maximum length * when more datagrams have been received. If you want the next * method in the queue to handle the datagram received next, you * need to return false from the method. * @param selector The selector to call on the target. The signature must be * `bool (OFUDPSocket *socket, void *buffer, size_t length, | | | 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 | * datagram has been received. If the method returns true, it * will be called again with the same buffer and maximum length * when more datagrams have been received. If you want the next * method in the queue to handle the datagram received next, you * need to return false from the method. * @param selector The selector to call on the target. The signature must be * `bool (OFUDPSocket *socket, void *buffer, size_t length, * of_udp_socket_address_t sender, id context, id exception)`. * @param context A context object to pass along to the target */ - (void)asyncReceiveIntoBuffer: (void *)buffer length: (size_t)length target: (id)target selector: (SEL)selector context: (nullable id)context; |
︙ | ︙ | |||
243 244 245 246 247 248 249 250 251 252 253 254 255 256 | * @param receiver A pointer to an @ref of_udp_socket_address_t to which the * datagram should be sent */ - (void)sendBuffer: (const void *)buffer length: (size_t)length receiver: (const of_udp_socket_address_t *)receiver; /*! * @brief Cancels all pending asynchronous requests on the socket. */ - (void)cancelAsyncRequests; /*! * @brief Closes the socket so that it can neither receive nor send any more | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 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 319 320 321 322 323 324 | * @param receiver A pointer to an @ref of_udp_socket_address_t to which the * datagram should be sent */ - (void)sendBuffer: (const void *)buffer length: (size_t)length receiver: (const of_udp_socket_address_t *)receiver; /*! * @brief Asynchronously sends the specified datagram to the specified address. * * @param buffer The buffer to send as a datagram * @param length The length of the buffer * @param receiver A pointer to an @ref of_udp_socket_address_t to which the * datagram should be sent * @param target The target on which the selector should be called when the * packet has been sent. The method should return the length for * the next send with the same callback or 0 if it should not * repeat. The buffer and receiver may be changed, so that every * time a new buffer, length and receiver can be specified while * the callback stays the same. * @param selector The selector to call on the target. The signature must be * `size_t (OFUDPSocket *socket, const void **buffer, * size_t bytesSent, of_udp_socket_address_t *receiver, * id context, id exception)`. * @param context A context object to pass along to the target */ - (void)asyncSendBuffer: (const void *)buffer length: (size_t)length receiver: (of_udp_socket_address_t)receiver target: (id)target selector: (SEL)selector context: (nullable id)context; #ifdef OF_HAVE_BLOCKS /*! * @brief Asynchronously sends the specified datagram to the specified address. * * @param buffer The buffer to send as a datagram * @param length The length of the buffer * @param receiver A pointer to an @ref of_udp_socket_address_t to which the * datagram should be sent * @param block The block to call when the packet has been sent. It should * return the length for the next send with the same callback or 0 * if it should not repeat. The buffer and receiver may be * changed, so that every time a new buffer, length and receiver * can be specified while the callback stays the same. */ - (void)asyncSendBuffer: (const void *)buffer length: (size_t)length receiver: (of_udp_socket_address_t)receiver block: (of_udp_socket_async_send_block_t)block; #endif /*! * @brief Cancels all pending asynchronous requests on the socket. */ - (void)cancelAsyncRequests; /*! * @brief Closes the socket so that it can neither receive nor send any more |
︙ | ︙ |
Modified src/OFUDPSocket.m from [971c30a9d2] to [35a4b455a8].
︙ | ︙ | |||
628 629 630 631 632 633 634 635 636 637 638 639 640 641 | if ((size_t)bytesWritten != length) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length bytesWritten: bytesWritten errNo: 0]; } - (void)cancelAsyncRequests { [OFRunLoop of_cancelAsyncRequestsForObject: self]; } - (int)fileDescriptorForReading | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 | if ((size_t)bytesWritten != length) @throw [OFWriteFailedException exceptionWithObject: self requestedLength: length bytesWritten: bytesWritten errNo: 0]; } - (void)asyncSendBuffer: (const void *)buffer length: (size_t)length receiver: (of_udp_socket_address_t)receiver target: (id)target selector: (SEL)selector context: (id)context { [OFRunLoop of_addAsyncSendForUDPSocket: self buffer: buffer length: length receiver: receiver target: target selector: selector context: context]; } #ifdef OF_HAVE_BLOCKS - (void)asyncSendBuffer: (const void *)buffer length: (size_t)length receiver: (of_udp_socket_address_t)receiver block: (of_udp_socket_async_send_block_t)block { [OFRunLoop of_addAsyncSendForUDPSocket: self buffer: buffer length: length receiver: receiver block: block]; } #endif - (void)cancelAsyncRequests { [OFRunLoop of_cancelAsyncRequestsForObject: self]; } - (int)fileDescriptorForReading |
︙ | ︙ |