X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=lib%2Fgraph%2Fnotification%2Fevent.c;h=ad5d5dd1eb634d694536f560e23246455b454d85;hb=6c677fb54f458456e3b5a15cffa6774bd7a86f54;hp=3ed1c4cd0f6b6d351619bbdcd2497755c72d4c8b;hpb=3fea54f69edd1780566230255da196cb6e82df62;p=babeltrace.git diff --git a/lib/graph/notification/event.c b/lib/graph/notification/event.c index 3ed1c4cd..ad5d5dd1 100644 --- a/lib/graph/notification/event.c +++ b/lib/graph/notification/event.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -82,22 +83,11 @@ struct bt_notification *bt_notification_event_create( struct bt_clock_class_priority_map *cc_prio_map) { struct bt_notification_event *notification = NULL; + struct bt_event *event; BT_ASSERT_PRE_NON_NULL(event_class, "Event class"); BT_ASSERT_PRE_NON_NULL(packet, "Packet"); - - if (cc_prio_map) { - /* Function's reference, released at the end */ - bt_get(cc_prio_map); - } else { - cc_prio_map = bt_clock_class_priority_map_create(); - if (!cc_prio_map) { - BT_LOGE_STR("Cannot create empty clock class priority map."); - goto error; - } - } - - BT_ASSERT(cc_prio_map); + BT_ASSERT_PRE_NON_NULL(cc_prio_map, "Clock class priority map"); BT_LOGD("Creating event notification object: " "event-class-addr=%p, " "event-class-name=\"%s\", event-class-id=%" PRId64 ", " @@ -105,24 +95,43 @@ struct bt_notification *bt_notification_event_create( event_class, bt_event_class_get_name(event_class), bt_event_class_get_id(event_class), cc_prio_map); - BT_ASSERT_PRE(event_class_has_trace(event_class), "Event class is not part of a trace: %!+E", event_class); - notification = (void *) bt_notification_create_from_pool( - &graph->event_notif_pool, graph); - if (!notification) { - /* bt_notification_create_from_pool() logs errors */ + event = bt_event_create(event_class, packet); + if (unlikely(!event)) { + BT_LIB_LOGE("Cannot create event from event class: " + "%![event-class-]+E", event_class); goto error; } - notification->event = bt_event_create(event_class, packet); - if (!notification->event) { - BT_LIB_LOGE("Cannot create event from event class: " - "%![event-class-]+E", event_class); + /* + * Create notification from pool _after_ we have everything + * (in this case, a valid event object) so that we never have an + * error condition with a non-NULL notification object. + * Otherwise: + * + * * We cannot recycle the notification on error because + * bt_notification_event_recycle() expects a complete + * notification (and the event or clock class priority map + * object could be unset). + * + * * We cannot destroy the notification because we would need + * to notify the graph (pool owner) so that it removes the + * notification from its notification array. + */ + notification = (void *) bt_notification_create_from_pool( + &graph->event_notif_pool, graph); + if (unlikely(!notification)) { + /* bt_notification_create_from_pool() logs errors */ goto error; } - notification->cc_prio_map = bt_get(cc_prio_map); + BT_ASSERT(!notification->cc_prio_map); + notification->cc_prio_map = cc_prio_map; + bt_object_get_no_null_check_no_parent_check( + ¬ification->cc_prio_map->base); + BT_ASSERT(!notification->event); + notification->event = event; BT_LOGD_STR("Freezing event notification's clock class priority map."); bt_clock_class_priority_map_freeze(notification->cc_prio_map); BT_LOGD("Created event notification object: " @@ -136,10 +145,10 @@ struct bt_notification *bt_notification_event_create( goto end; error: - BT_PUT(notification); + BT_ASSERT(!notification); + bt_event_destroy(event); end: - bt_put(cc_prio_map); return (void *) notification; } @@ -168,21 +177,19 @@ void bt_notification_event_recycle(struct bt_notification *notif) BT_ASSERT(event_notif); - if (!notif->graph) { + if (unlikely(!notif->graph)) { bt_notification_event_destroy(notif); return; } BT_LOGD("Recycling event notification: addr=%p", notif); bt_notification_reset(notif); - - if (event_notif->event) { - BT_LOGD_STR("Recycling event."); - bt_event_recycle(event_notif->event); - event_notif->event = NULL; - } - - BT_PUT(event_notif->cc_prio_map); + BT_ASSERT(event_notif->event); + BT_LOGD_STR("Recycling event."); + bt_event_recycle(event_notif->event); + event_notif->event = NULL; + bt_object_put_no_null_check(&event_notif->cc_prio_map->base); + event_notif->cc_prio_map = NULL; graph = notif->graph; notif->graph = NULL; bt_object_pool_recycle_object(&graph->event_notif_pool, notif);