@@ -352,23 +352,54 @@ RMW_WARN_UNUSED
352
352
rmw_ret_t
353
353
rmw_destroy_publisher (rmw_node_t * node , rmw_publisher_t * publisher );
354
354
355
- /// Borrow a loaned message.
355
+ /// Borrow a loaned ROS message.
356
356
/**
357
- * The memory allocated for the ros message belongs to the middleware and must not be deallocated.
358
- * A call to \sa rmw_publish_loned_message as well as \sa rmw_return_loaned_message_from_publisher`
359
- * will return ownership of the loaned message back to the middleware.
360
- *
361
- * In order to react to failures, the ros message is passed by pointer as an output parameter.
362
- * Therefore, the pointer to the ros message has to be `null` and not previously allocated or
363
- * else that memory is lost.
364
- *
365
- * \param[in] publisher Publisher to which the allocated message is associated.
366
- * \param[in] type_support Typesupport to which the internal ros message is allocated.
367
- * \param[out] ros_message The pointer to be filled with a valid ros message by the middleware.
368
- * \return `RMW_RET_OK` if the ros message was correctly initialized, or
369
- * \return `RMW_RET_INVALID_ARGUMENT` if an argument other than the ros message is null, or
370
- * \return `RMW_RET_BAD_ALLOC` if the ros message could not be correctly created, or
371
- * \return `RMW_RET_UNSUPPORTED` if the rmw_implementation does not support loaned_message, or
357
+ * This ROS message is owned by the middleware, that will keep it alive (i.e. in valid
358
+ * memory space) until the caller publishes it using rmw_publish_loaned_message() or
359
+ * returns it using rmw_return_loaned_message_from_publisher().
360
+ *
361
+ * <hr>
362
+ * Attribute | Adherence
363
+ * ------------------ | -------------
364
+ * Allocates Memory | Maybe
365
+ * Thread-Safe | Yes
366
+ * Uses Atomics | Maybe [1]
367
+ * Lock-Free | Maybe [1]
368
+ *
369
+ * <i>[1] implementation defined, check implementation documentation.</i>
370
+ *
371
+ * \par Runtime behavior
372
+ * To borrow a ROS message is a synchronous operation.
373
+ * It is also non-blocking, but it is not guaranteed to be lock-free.
374
+ * Generally speaking, implementations may synchronize access to internal resources using
375
+ * locks but are not allowed to wait for events with no guaranteed time bound (barring
376
+ * the effects of starvation due to OS scheduling).
377
+ *
378
+ * \par Memory allocation
379
+ * It is implementation defined whether memory will be allocated on borrow or not.
380
+ * Check the implementation documentation to learn about memory allocation
381
+ * guarantees when using ROS message loaning support.
382
+ *
383
+ * \par Thread-safety
384
+ * Publishers are thread-safe objects, and so are all operations on them except for finalization.
385
+ * Therefore, it is safe to borrow ROS messages from the same publisher concurrently.
386
+ *
387
+ * \pre Given `publisher` must be a valid publisher, as returned by rmw_create_publisher().
388
+ * \pre Given `type_support` must be a valid `rosidl` message type support, matching the
389
+ * one registered with the `publisher` on creation.
390
+ *
391
+ * \param[in] publisher Publisher to which the loaned ROS message will be associated.
392
+ * \param[in] type_support Message type support of the loaned ROS message.
393
+ * \param[out] ros_message Pointer to type erased ROS message loaned by the middleware.
394
+ * \return `RMW_RET_OK` if successful, or
395
+ * \return `RMW_RET_BAD_ALLOC` if memory allocation fails, or
396
+ * \return `RMW_RET_INVALID_ARGUMENT` if `publisher` is NULL, or
397
+ * \return `RMW_RET_INVALID_ARGUMENT` if `type_support` is NULL, or
398
+ * \return `RMW_RET_INVALID_ARGUMENT` if `ros_message` is NULL, or
399
+ * \return `RMW_RET_INVALID_ARGUMENT` if `*ros_message` is not NULL (to prevent leaks), or
400
+ * \return `RMW_RET_INCORRECT_RMW_IMPLEMENTATION` if `publisher` implementation identifier
401
+ * does not match this implementation, or
402
+ * \return `RMW_RET_UNSUPPORTED` if the implementation does not support ROS message loaning, or
372
403
* \return `RMW_RET_ERROR` if an unexpected error occured.
373
404
*/
374
405
RMW_PUBLIC
@@ -379,17 +410,52 @@ rmw_borrow_loaned_message(
379
410
const rosidl_message_type_support_t * type_support ,
380
411
void * * ros_message );
381
412
382
- /// Return a loaned message previously borrow from a publisher.
413
+ /// Return a loaned message previously borrowed from a publisher.
383
414
/**
384
- * The ownership of the passed in ros message will be transferred back to the middleware.
385
- * The middleware might deallocate and destroy the message so that the pointer is no longer
386
- * guaranteed to be valid after this call.
415
+ * Tells the middleware that a borrowed ROS message is no longer needed by the caller.
416
+ * Ownership of the ROS message is given back to the middleware.
417
+ * If this function fails early due to a logical error, such as an invalid argument,
418
+ * the loaned ROS message will be left unchanged.
419
+ * Otherwise, ownership of the ROS message will be given back to the middleware.
420
+ * It is up to the middleware what will be made of the returned ROS message.
421
+ * It is undefined behavior to use a loaned ROS message after returning it.
422
+ *
423
+ * <hr>
424
+ * Attribute | Adherence
425
+ * ------------------ | -------------
426
+ * Allocates Memory | No
427
+ * Thread-Safe | Yes
428
+ * Uses Atomics | Maybe [1]
429
+ * Lock-Free | Maybe [1]
430
+ *
431
+ * <i>[1] implementation defined, check implementation documentation.</i>
432
+ *
433
+ * \par Runtime behavior
434
+ * To return a ROS message is a synchronous operation.
435
+ * It is also non-blocking, but it is not guaranteed to be lock-free.
436
+ * Generally speaking, implementations may synchronize access to internal resources using
437
+ * locks but are not allowed to wait for events with no guaranteed time bound (barring
438
+ * the effects of starvation due to OS scheduling).
387
439
*
388
- * \param[in] publisher Publisher to which the loaned message is associated.
389
- * \param[in] loaned_message Loaned message to be returned.
440
+ * \par Thread-safety
441
+ * Publishers are thread-safe objects, and so are all operations on them except for finalization.
442
+ * Therefore, it is safe to return borrowed ROS messages to the same publisher concurrently.
443
+ * However, since ownership of the loaned ROS message is given back to the middleware and
444
+ * this transfer is not synchronized, it is not safe to return the same loaned ROS message
445
+ * concurrently.
446
+ *
447
+ * \pre Given `publisher` must be a valid publisher, as returned by rmw_create_publisher().
448
+ * \pre Given `loaned_message` must have been previously borrowed from the same publisher
449
+ * using rmw_borrow_loaned_message().
450
+ *
451
+ * \param[in] publisher Publisher to which the loaned ROS message is associated.
452
+ * \param[in] loaned_message Type erased loaned ROS message to be returned.
390
453
* \return `RMW_RET_OK` if successful, or
391
- * \return `RMW_RET_INVALID_ARGUMENT` if an argument is null, or
392
- * \return `RMW_RET_UNSUPPORTED` if the rmw_implementation does not support loaned_message, or
454
+ * \return `RMW_RET_INVALID_ARGUMENT` if `publisher` is NULL, or
455
+ * \return `RMW_RET_INVALID_ARGUMENT` if `loaned_message` is NULL, or
456
+ * \return `RMW_RET_INCORRECT_RMW_IMPLEMENTATION` if `publisher` implementation identifier
457
+ * does not match this implementation, or
458
+ * \return `RMW_RET_UNSUPPORTED` if the implementation does not support ROS message loaning, or
393
459
* \return `RMW_RET_ERROR` if an unexpected error occurs and no message can be initialized.
394
460
*/
395
461
RMW_PUBLIC
@@ -399,15 +465,62 @@ rmw_return_loaned_message_from_publisher(
399
465
const rmw_publisher_t * publisher ,
400
466
void * loaned_message );
401
467
402
- /// Publish a given ros_message
468
+ /// Publish a ROS message.
403
469
/**
404
- * Publish a given ROS message via a publisher.
470
+ * Send a ROS message to all subscriptions with matching QoS policies using the given publisher.
471
+ *
472
+ * <hr>
473
+ * Attribute | Adherence
474
+ * ------------------ | -------------
475
+ * Allocates Memory | Maybe
476
+ * Thread-Safe | Yes
477
+ * Uses Atomics | Maybe [1]
478
+ * Lock-Free | Maybe [1]
479
+ *
480
+ * <i>[1] implementation defined, check implementation documentation.</i>
481
+ *
482
+ * \par Runtime behavior
483
+ * It is implementation defined whether to publish a ROS message is a
484
+ * synchronous or asynchronous, blocking or non-blocking operation.
485
+ * However, asynchronous implementations are not allowed to access the
486
+ * given ROS message after this function returns.
487
+ * Check the implementation documentation to learn about publish behavior.
488
+ *
489
+ * \par Memory allocation
490
+ * It is implementation defined whether memory will be allocated on publish or not.
491
+ * For instance, implementations that serialize ROS messages to send it over the
492
+ * wire may need to perform additional memory allocations when dealing with
493
+ * unbounded (dynamically-sized) fields.
494
+ * A publisher allocation, if provided, may or may not be used.
495
+ * Check the implementation documentation to learn about memory allocation
496
+ * guarantees when publishing ROS messages with and without publisher allocations.
497
+ *
498
+ * \par Thread-safety
499
+ * Publishers are thread-safe objects, and so are all operations on them except for finalization.
500
+ * Therefore, it is safe to publish using the same publisher concurrently.
501
+ * However, when publishing regular ROS messages:
502
+ * - Access to the ROS message is read-only but it is not synchronized.
503
+ * Concurrent `ros_message` reads are safe, but concurrent reads and writes are not.
504
+ * - Access to the publisher allocation is not synchronized, unless specifically stated
505
+ * otherwise by the implementation.
506
+ * Thus, it is generally not safe to read or write `allocation` while rmw_publish() uses it.
507
+ * Check the implementation documentation to learn about publisher allocations' thread-safety.
508
+ *
509
+ * \pre Given `publisher` must be a valid publisher, as returned by rmw_create_publisher().
510
+ * \pre Given `ros_message` must be a valid message, whose type matches the message type
511
+ * support the `publisher` was registered with on creation.
512
+ * \pre If not NULL, given `allocation` must be a valid publisher allocation, initialized
513
+ * with rmw_publisher_allocation_init() with a message type support that matches the
514
+ * one registered with `publisher` on creation.
405
515
*
406
516
* \param[in] publisher Publisher to be used to send message.
407
- * \param[in] ros_message Message to be sent.
408
- * \param[in] allocation Specify preallocated memory to use (may be NULL) .
517
+ * \param[in] ros_message Type erased ROS message to be sent.
518
+ * \param[in] allocation Pre-allocated memory to be used. May be NULL.
409
519
* \return `RMW_RET_OK` if successful, or
410
- * \return `RMW_RET_INVALID_ARGUMENT` if publisher or ros_message is null, or
520
+ * \return `RMW_RET_INVALID_ARGUMENT` if `publisher` is NULL, or
521
+ * \return `RMW_RET_INVALID_ARGUMENT` if `ros_message` is NULL, or
522
+ * \return `RMW_RET_INCORRECT_RMW_IMPLEMENTATION` if `publisher` implementation
523
+ * identifier does not match this implementation, or
411
524
* \return `RMW_RET_ERROR` if an unexpected error occurs.
412
525
*/
413
526
RMW_PUBLIC
@@ -418,23 +531,69 @@ rmw_publish(
418
531
const void * ros_message ,
419
532
rmw_publisher_allocation_t * allocation );
420
533
421
- /// Publish a loaned ros_message .
534
+ /// Publish a loaned ROS message .
422
535
/**
423
- * Publish a loaned ROS message via a publisher and return ownership of the loaned message
424
- * back to the middleware.
536
+ * Send a previously borrowed ROS message to all subscriptions with matching QoS policies
537
+ * using the given publisher, then return ROS message ownership to the middleware.
538
+ *
539
+ * If this function fails early due to a logical error, such as an invalid argument,
540
+ * the loaned ROS message will be left unchanged.
541
+ * Otherwise, ownership of the ROS message will be given back to the middleware.
542
+ * It is up to the middleware what will be made of the returned ROS message.
543
+ * It is undefined behavior to use a loaned ROS message after publishing it.
544
+ *
545
+ * <hr>
546
+ * Attribute | Adherence
547
+ * ------------------ | -------------
548
+ * Allocates Memory | Maybe
549
+ * Thread-Safe | Yes
550
+ * Uses Atomics | Maybe [1]
551
+ * Lock-Free | Maybe [1]
425
552
*
426
- * In contrast to \sa `rmw_publish` the ownership of the ros message is being transferred to the
427
- * middleware which might deallocate the memory for it.
428
- * Similar to \sa `rmw_return_loaned_message_from_publisher` the passed in ros message might
429
- * not be valid after this call and thus should only be called with messages previously loaned with
430
- * a call to \sa `rmw_borrow_loaned_message`.
553
+ * <i>[1] implementation defined, check the implementation documentation.</i>
554
+ *
555
+ * \par Runtime behavior
556
+ * It is implementation defined whether to publish a loaned ROS message is a
557
+ * synchronous or asynchronous, blocking or non-blocking operation.
558
+ * Check the implementation documentation to learn about publish behavior.
559
+ *
560
+ * \par Memory allocation
561
+ * It is implementation defined whether memory will be allocated on publish or not.
562
+ * For instance, implementations that serialize ROS messages to send it over the
563
+ * wire may need to perform additional memory allocations when dealing with
564
+ * unbounded (dynamically-sized) fields.
565
+ * A publisher allocation, if provided, may or may not be used.
566
+ * Check the implementation documentation to learn about memory allocation
567
+ * guarantees when publishing loaned ROS messages with and without publisher allocations.
568
+ *
569
+ * \par Thread-safety
570
+ * Publishers are thread-safe objects, and so are all operations on them except for finalization.
571
+ * Therefore, it is safe to publish using the same publisher concurrently.
572
+ * However, when publishing loaned ROS messages:
573
+ * - Ownership of the loaned ROS message is given back to the middleware.
574
+ * This transfer is not synchronized, and thus it is not safe to publish the
575
+ * same loaned ROS message concurrently.
576
+ * - Access to the publisher allocation is not synchronized, unless specifically stated
577
+ * otherwise by the implementation.
578
+ * Thus, it is generally not safe to read or write `allocation` while rmw_publish() uses it.
579
+ * Check the implementation documentation to learn about publisher allocations' thread-safety.
580
+ *
581
+ * \pre Given `publisher` must be a valid publisher, as returned by rmw_create_publisher().
582
+ * \pre Given `ros_message` must be a valid message, borrowed from the same publisher using
583
+ * rmw_borrow_loaned_message().
584
+ * \pre If not NULL, given `allocation` must be a valid publisher allocation, initialized
585
+ * with rmw_publisher_allocation_init() with a message type support that matches the
586
+ * one registered with `publisher` on creation.
431
587
*
432
588
* \param[in] publisher Publisher to be used to send message.
433
- * \param[in] ros_message Message to be sent.
434
- * \param[in] allocation Specify preallocated memory to use (may be NULL) .
589
+ * \param[in] ros_message Loaned type erased ROS message to be sent.
590
+ * \param[in] allocation Pre-allocated memory to be used. May be NULL.
435
591
* \return `RMW_RET_OK` if successful, or
436
- * \return `RMW_RET_INVALID_ARGUMENT` if publisher or ros_message is null, or
437
- * \return `RMW_RET_UNSUPPORTED` if the rmw_implementation does not support loaned_message, or
592
+ * \return `RMW_RET_INVALID_ARGUMENT` if `publisher` is NULL, or
593
+ * \return `RMW_RET_INVALID_ARGUMENT` if `ros_message` is NULL, or
594
+ * \return `RMW_RET_INCORRECT_RMW_IMPLEMENTATION` if `publisher` implementation
595
+ * identifier does not match this implementation, or
596
+ * \return `RMW_RET_UNSUPPORTED` if the implementation does not support ROS message loaning, or
438
597
* \return `RMW_RET_ERROR` if an unexpected error occurs.
439
598
*/
440
599
RMW_PUBLIC
@@ -512,18 +671,62 @@ rmw_publisher_get_actual_qos(
512
671
const rmw_publisher_t * publisher ,
513
672
rmw_qos_profile_t * qos );
514
673
515
- /// Publish an already serialized message.
674
+ /// Publish a ROS message as a byte stream .
516
675
/**
517
- * The publisher must already be registered with the correct message type
518
- * support so that it can send serialized data corresponding to that type.
519
- * This function sends the serialized byte stream directly over the wire without
520
- * having to serialize the message first.
521
- * A ROS message can be serialized manually using the rmw_serialize() function.
522
- *
523
- * \param[in] publisher The publisher object registered to send the message.
524
- * \param[in] serialized_message The serialized message holding the byte stream.
525
- * \param[in] allocation Specify preallocated memory to use (may be NULL).
676
+ * Send a ROS message serialized as a byte stream to all subscriptions with
677
+ * matching QoS policies using the given publisher.
678
+ * A ROS message can be serialized manually using rmw_serialize().
679
+ *
680
+ * <hr>
681
+ * Attribute | Adherence
682
+ * ------------------ | -------------
683
+ * Allocates Memory | Maybe
684
+ * Thread-Safe | Yes
685
+ * Uses Atomics | Maybe [1]
686
+ * Lock-Free | Maybe [1]
687
+ *
688
+ * <i>[1] implementation defined, check the implementation documentation.</i>
689
+ *
690
+ * \par Runtime behavior
691
+ * It is implementation defined whether to publish a loaned ROS message is a
692
+ * synchronous or asynchronous, blocking or non-blocking operation.
693
+ * However, asynchronous implementations are not allowed to access the
694
+ * given byte stream after this function returns.
695
+ * Check the implementation documentation to learn about publish behavior.
696
+ *
697
+ * \par Memory allocation
698
+ * It is implementation defined whether memory will be allocated on publish or not.
699
+ * Even if a publisher allocation is provided, an implementation may ignore it.
700
+ * Check the implementation documentation to learn about memory allocation
701
+ * guarantees when publishing serialized messages with and without publisher allocations.
702
+ *
703
+ * \par Thread-safety
704
+ * Publishers are thread-safe objects, and so are all operations on them except for finalization.
705
+ * Therefore, it is safe to publish using the same publisher concurrently.
706
+ * However, when publishing serialized ROS messages:
707
+ * - Access to the byte stream is read-only but it is not synchronized.
708
+ * Concurrent `serialized_message` reads are safe, but concurrent reads and writes are not.
709
+ * - Access to the publisher allocation is not synchronized, unless specifically stated
710
+ * otherwise by the implementation.
711
+ * Thus, it is generally not safe to read or write `allocation` while rmw_publish() uses it.
712
+ * Check the implementation documentation to learn about publisher allocations' thread-safety.
713
+ *
714
+ * \pre Given `publisher` must be a valid publisher, as returned by rmw_create_publisher().
715
+ * \pre Given `serialized_message` must be a valid serialized message, initialized by
716
+ * rmw_serialized_message_init() and containing the serialization of a ROS message whose
717
+ * type matches the message type support the `publisher` was registered with on creation.
718
+ * \pre If not NULL, given `allocation` must be a valid publisher allocation, initialized
719
+ * with rmw_publisher_allocation_init() with a message type support that matches the
720
+ * one registered with `publisher` on creation.
721
+ *
722
+ * \param[in] publisher Publisher to be used to send message.
723
+ * \param[in] ros_message Serialized ROS message to be sent.
724
+ * \param[in] allocation Pre-allocated memory to be used. May be NULL.
526
725
* \return `RMW_RET_OK` if successful, or
726
+ * \return `RMW_RET_INVALID_ARGUMENT` if `publisher` is NULL, or
727
+ * \return `RMW_RET_INVALID_ARGUMENT` if `serialized_message` is NULL, or
728
+ * \return `RMW_RET_INCORRECT_RMW_IMPLEMENTATION` if `publisher` implementation
729
+ * identifier does not match this implementation, or
527
730
* \return `RMW_RET_ERROR` if an unexpected error occurs.
528
731
*/
529
732
RMW_PUBLIC
0 commit comments