LCOV - code coverage report
Current view: top level - libsystemd/sd-bus - bus-slot.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 110 165 66.7 %
Date: 2019-08-23 13:36:53 Functions: 8 17 47.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 81 193 42.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : 
       3                 :            : #include "sd-bus.h"
       4                 :            : 
       5                 :            : #include "alloc-util.h"
       6                 :            : #include "bus-control.h"
       7                 :            : #include "bus-objects.h"
       8                 :            : #include "bus-slot.h"
       9                 :            : #include "string-util.h"
      10                 :            : 
      11                 :        368 : sd_bus_slot *bus_slot_allocate(
      12                 :            :                 sd_bus *bus,
      13                 :            :                 bool floating,
      14                 :            :                 BusSlotType type,
      15                 :            :                 size_t extra,
      16                 :            :                 void *userdata) {
      17                 :            : 
      18                 :            :         sd_bus_slot *slot;
      19                 :            : 
      20         [ -  + ]:        368 :         assert(bus);
      21                 :            : 
      22                 :        368 :         slot = malloc0(offsetof(sd_bus_slot, reply_callback) + extra);
      23         [ -  + ]:        368 :         if (!slot)
      24                 :          0 :                 return NULL;
      25                 :            : 
      26                 :        368 :         slot->n_ref = 1;
      27                 :        368 :         slot->type = type;
      28                 :        368 :         slot->bus = bus;
      29                 :        368 :         slot->floating = floating;
      30                 :        368 :         slot->userdata = userdata;
      31                 :            : 
      32         [ +  + ]:        368 :         if (!floating)
      33                 :         72 :                 sd_bus_ref(bus);
      34                 :            : 
      35   [ -  +  +  + ]:        368 :         LIST_PREPEND(slots, bus->slots, slot);
      36                 :            : 
      37                 :        368 :         return slot;
      38                 :            : }
      39                 :            : 
      40                 :        765 : void bus_slot_disconnect(sd_bus_slot *slot, bool unref) {
      41                 :            :         sd_bus *bus;
      42                 :            : 
      43         [ -  + ]:        765 :         assert(slot);
      44                 :            : 
      45         [ +  + ]:        765 :         if (!slot->bus)
      46                 :        397 :                 return;
      47                 :            : 
      48   [ +  -  +  +  :        368 :         switch (slot->type) {
             +  +  +  - ]
      49                 :            : 
      50                 :        180 :         case BUS_REPLY_CALLBACK:
      51                 :            : 
      52         [ +  + ]:        180 :                 if (slot->reply_callback.cookie != 0)
      53                 :         57 :                         ordered_hashmap_remove(slot->bus->reply_callbacks, &slot->reply_callback.cookie);
      54                 :            : 
      55         [ +  + ]:        180 :                 if (slot->reply_callback.timeout_usec != 0)
      56                 :         57 :                         prioq_remove(slot->bus->reply_callbacks_prioq, &slot->reply_callback, &slot->reply_callback.prioq_idx);
      57                 :            : 
      58                 :        180 :                 break;
      59                 :            : 
      60                 :          0 :         case BUS_FILTER_CALLBACK:
      61                 :          0 :                 slot->bus->filter_callbacks_modified = true;
      62   [ #  #  #  #  :          0 :                 LIST_REMOVE(callbacks, slot->bus->filter_callbacks, &slot->filter_callback);
             #  #  #  # ]
      63                 :          0 :                 break;
      64                 :            : 
      65                 :        120 :         case BUS_MATCH_CALLBACK:
      66                 :            : 
      67         [ +  + ]:        120 :                 if (slot->match_added)
      68                 :         68 :                         (void) bus_remove_match_internal(slot->bus, slot->match_callback.match_string);
      69                 :            : 
      70         [ +  + ]:        120 :                 if (slot->match_callback.install_slot) {
      71                 :         41 :                         bus_slot_disconnect(slot->match_callback.install_slot, true);
      72                 :         41 :                         slot->match_callback.install_slot = sd_bus_slot_unref(slot->match_callback.install_slot);
      73                 :            :                 }
      74                 :            : 
      75                 :        120 :                 slot->bus->match_callbacks_modified = true;
      76                 :        120 :                 bus_match_remove(&slot->bus->match_callbacks, &slot->match_callback);
      77                 :            : 
      78                 :        120 :                 slot->match_callback.match_string = mfree(slot->match_callback.match_string);
      79                 :            : 
      80                 :        120 :                 break;
      81                 :            : 
      82                 :          4 :         case BUS_NODE_CALLBACK:
      83                 :            : 
      84         [ +  - ]:          4 :                 if (slot->node_callback.node) {
      85   [ -  +  -  +  :          4 :                         LIST_REMOVE(callbacks, slot->node_callback.node->callbacks, &slot->node_callback);
             -  +  -  + ]
      86                 :          4 :                         slot->bus->nodes_modified = true;
      87                 :            : 
      88                 :          4 :                         bus_node_gc(slot->bus, slot->node_callback.node);
      89                 :            :                 }
      90                 :            : 
      91                 :          4 :                 break;
      92                 :            : 
      93                 :          8 :         case BUS_NODE_ENUMERATOR:
      94                 :            : 
      95         [ +  - ]:          8 :                 if (slot->node_enumerator.node) {
      96   [ -  +  -  +  :          8 :                         LIST_REMOVE(enumerators, slot->node_enumerator.node->enumerators, &slot->node_enumerator);
             -  +  -  + ]
      97                 :          8 :                         slot->bus->nodes_modified = true;
      98                 :            : 
      99                 :          8 :                         bus_node_gc(slot->bus, slot->node_enumerator.node);
     100                 :            :                 }
     101                 :            : 
     102                 :          8 :                 break;
     103                 :            : 
     104                 :          8 :         case BUS_NODE_OBJECT_MANAGER:
     105                 :            : 
     106         [ +  - ]:          8 :                 if (slot->node_object_manager.node) {
     107   [ -  +  -  +  :          8 :                         LIST_REMOVE(object_managers, slot->node_object_manager.node->object_managers, &slot->node_object_manager);
             -  +  -  + ]
     108                 :          8 :                         slot->bus->nodes_modified = true;
     109                 :            : 
     110                 :          8 :                         bus_node_gc(slot->bus, slot->node_object_manager.node);
     111                 :            :                 }
     112                 :            : 
     113                 :          8 :                 break;
     114                 :            : 
     115                 :         48 :         case BUS_NODE_VTABLE:
     116                 :            : 
     117   [ +  -  +  -  :         48 :                 if (slot->node_vtable.node && slot->node_vtable.interface && slot->node_vtable.vtable) {
                   +  - ]
     118                 :            :                         const sd_bus_vtable *v;
     119                 :            : 
     120         [ +  + ]:        524 :                         for (v = slot->node_vtable.vtable; v->type != _SD_BUS_VTABLE_END; v = bus_vtable_next(slot->node_vtable.vtable, v)) {
     121                 :        476 :                                 struct vtable_member *x = NULL;
     122                 :            : 
     123      [ +  +  + ]:        476 :                                 switch (v->type) {
     124                 :            : 
     125                 :        208 :                                 case _SD_BUS_VTABLE_METHOD: {
     126                 :            :                                         struct vtable_member key;
     127                 :            : 
     128                 :        208 :                                         key.path = slot->node_vtable.node->path;
     129                 :        208 :                                         key.interface = slot->node_vtable.interface;
     130                 :        208 :                                         key.member = v->x.method.member;
     131                 :            : 
     132                 :        208 :                                         x = hashmap_remove(slot->bus->vtable_methods, &key);
     133                 :        208 :                                         break;
     134                 :            :                                 }
     135                 :            : 
     136                 :        172 :                                 case _SD_BUS_VTABLE_PROPERTY:
     137                 :            :                                 case _SD_BUS_VTABLE_WRITABLE_PROPERTY: {
     138                 :            :                                         struct vtable_member key;
     139                 :            : 
     140                 :        172 :                                         key.path = slot->node_vtable.node->path;
     141                 :        172 :                                         key.interface = slot->node_vtable.interface;
     142                 :        172 :                                         key.member = v->x.method.member;
     143                 :            : 
     144                 :        172 :                                         x = hashmap_remove(slot->bus->vtable_properties, &key);
     145                 :        172 :                                         break;
     146                 :            :                                 }}
     147                 :            : 
     148                 :        476 :                                 free(x);
     149                 :            :                         }
     150                 :            :                 }
     151                 :            : 
     152                 :         48 :                 slot->node_vtable.interface = mfree(slot->node_vtable.interface);
     153                 :            : 
     154         [ +  - ]:         48 :                 if (slot->node_vtable.node) {
     155   [ -  +  +  +  :         48 :                         LIST_REMOVE(vtables, slot->node_vtable.node->vtables, &slot->node_vtable);
             -  +  -  + ]
     156                 :         48 :                         slot->bus->nodes_modified = true;
     157                 :            : 
     158                 :         48 :                         bus_node_gc(slot->bus, slot->node_vtable.node);
     159                 :            :                 }
     160                 :            : 
     161                 :         48 :                 break;
     162                 :            : 
     163                 :          0 :         default:
     164                 :          0 :                 assert_not_reached("Wut? Unknown slot type?");
     165                 :            :         }
     166                 :            : 
     167                 :        368 :         bus = slot->bus;
     168                 :            : 
     169                 :        368 :         slot->type = _BUS_SLOT_INVALID;
     170                 :        368 :         slot->bus = NULL;
     171   [ -  +  +  +  :        368 :         LIST_REMOVE(slots, bus->slots, slot);
             +  +  -  + ]
     172                 :            : 
     173         [ +  + ]:        368 :         if (!slot->floating)
     174                 :         12 :                 sd_bus_unref(bus);
     175         [ +  - ]:        356 :         else if (unref)
     176                 :        356 :                 sd_bus_slot_unref(slot);
     177                 :            : }
     178                 :            : 
     179                 :        368 : static sd_bus_slot* bus_slot_free(sd_bus_slot *slot) {
     180         [ -  + ]:        368 :         assert(slot);
     181                 :            : 
     182                 :        368 :         bus_slot_disconnect(slot, false);
     183                 :            : 
     184         [ +  + ]:        368 :         if (slot->destroy_callback)
     185                 :          4 :                 slot->destroy_callback(slot->userdata);
     186                 :            : 
     187                 :        368 :         free(slot->description);
     188                 :        368 :         return mfree(slot);
     189                 :            : }
     190                 :            : 
     191   [ +  +  -  +  :      10004 : DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_bus_slot, sd_bus_slot, bus_slot_free);
                   +  + ]
     192                 :            : 
     193                 :          0 : _public_ sd_bus* sd_bus_slot_get_bus(sd_bus_slot *slot) {
     194   [ #  #  #  # ]:          0 :         assert_return(slot, NULL);
     195                 :            : 
     196                 :          0 :         return slot->bus;
     197                 :            : }
     198                 :            : 
     199                 :          0 : _public_ void *sd_bus_slot_get_userdata(sd_bus_slot *slot) {
     200   [ #  #  #  # ]:          0 :         assert_return(slot, NULL);
     201                 :            : 
     202                 :          0 :         return slot->userdata;
     203                 :            : }
     204                 :            : 
     205                 :          0 : _public_ void *sd_bus_slot_set_userdata(sd_bus_slot *slot, void *userdata) {
     206                 :            :         void *ret;
     207                 :            : 
     208   [ #  #  #  # ]:          0 :         assert_return(slot, NULL);
     209                 :            : 
     210                 :          0 :         ret = slot->userdata;
     211                 :          0 :         slot->userdata = userdata;
     212                 :            : 
     213                 :          0 :         return ret;
     214                 :            : }
     215                 :            : 
     216                 :          4 : _public_ int sd_bus_slot_set_destroy_callback(sd_bus_slot *slot, sd_bus_destroy_t callback) {
     217   [ -  +  -  + ]:          4 :         assert_return(slot, -EINVAL);
     218                 :            : 
     219                 :          4 :         slot->destroy_callback = callback;
     220                 :          4 :         return 0;
     221                 :            : }
     222                 :            : 
     223                 :         16 : _public_ int sd_bus_slot_get_destroy_callback(sd_bus_slot *slot, sd_bus_destroy_t *callback) {
     224   [ -  +  -  + ]:         16 :         assert_return(slot, -EINVAL);
     225                 :            : 
     226         [ +  + ]:         16 :         if (callback)
     227                 :          8 :                 *callback = slot->destroy_callback;
     228                 :            : 
     229                 :         16 :         return !!slot->destroy_callback;
     230                 :            : }
     231                 :            : 
     232                 :          0 : _public_ sd_bus_message *sd_bus_slot_get_current_message(sd_bus_slot *slot) {
     233   [ #  #  #  # ]:          0 :         assert_return(slot, NULL);
     234   [ #  #  #  # ]:          0 :         assert_return(slot->type >= 0, NULL);
     235                 :            : 
     236         [ #  # ]:          0 :         if (slot->bus->current_slot != slot)
     237                 :          0 :                 return NULL;
     238                 :            : 
     239                 :          0 :         return slot->bus->current_message;
     240                 :            : }
     241                 :            : 
     242                 :          0 : _public_ sd_bus_message_handler_t sd_bus_slot_get_current_handler(sd_bus_slot *slot) {
     243   [ #  #  #  # ]:          0 :         assert_return(slot, NULL);
     244   [ #  #  #  # ]:          0 :         assert_return(slot->type >= 0, NULL);
     245                 :            : 
     246         [ #  # ]:          0 :         if (slot->bus->current_slot != slot)
     247                 :          0 :                 return NULL;
     248                 :            : 
     249                 :          0 :         return slot->bus->current_handler;
     250                 :            : }
     251                 :            : 
     252                 :          0 : _public_ void* sd_bus_slot_get_current_userdata(sd_bus_slot *slot) {
     253   [ #  #  #  # ]:          0 :         assert_return(slot, NULL);
     254   [ #  #  #  # ]:          0 :         assert_return(slot->type >= 0, NULL);
     255                 :            : 
     256         [ #  # ]:          0 :         if (slot->bus->current_slot != slot)
     257                 :          0 :                 return NULL;
     258                 :            : 
     259                 :          0 :         return slot->bus->current_userdata;
     260                 :            : }
     261                 :            : 
     262                 :          0 : _public_ int sd_bus_slot_get_floating(sd_bus_slot *slot) {
     263   [ #  #  #  # ]:          0 :         assert_return(slot, -EINVAL);
     264                 :            : 
     265                 :          0 :         return slot->floating;
     266                 :            : }
     267                 :            : 
     268                 :         60 : _public_ int sd_bus_slot_set_floating(sd_bus_slot *slot, int b) {
     269   [ -  +  -  + ]:         60 :         assert_return(slot, -EINVAL);
     270                 :            : 
     271         [ -  + ]:         60 :         if (slot->floating == !!b)
     272                 :          0 :                 return 0;
     273                 :            : 
     274         [ -  + ]:         60 :         if (!slot->bus) /* already disconnected slots can't be reconnected */
     275                 :          0 :                 return -ESTALE;
     276                 :            : 
     277                 :         60 :         slot->floating = b;
     278                 :            : 
     279                 :            :         /* When a slot is "floating" then the bus references the slot. Otherwise the slot references the bus. Hence,
     280                 :            :          * when we move from one to the other, let's increase one reference and decrease the other. */
     281                 :            : 
     282         [ +  - ]:         60 :         if (b) {
     283                 :         60 :                 sd_bus_slot_ref(slot);
     284                 :         60 :                 sd_bus_unref(slot->bus);
     285                 :            :         } else {
     286                 :          0 :                 sd_bus_ref(slot->bus);
     287                 :          0 :                 sd_bus_slot_unref(slot);
     288                 :            :         }
     289                 :            : 
     290                 :         60 :         return 1;
     291                 :            : }
     292                 :            : 
     293                 :          0 : _public_ int sd_bus_slot_set_description(sd_bus_slot *slot, const char *description) {
     294   [ #  #  #  # ]:          0 :         assert_return(slot, -EINVAL);
     295                 :            : 
     296                 :          0 :         return free_and_strdup(&slot->description, description);
     297                 :            : }
     298                 :            : 
     299                 :          0 : _public_ int sd_bus_slot_get_description(sd_bus_slot *slot, const char **description) {
     300   [ #  #  #  # ]:          0 :         assert_return(slot, -EINVAL);
     301   [ #  #  #  # ]:          0 :         assert_return(description, -EINVAL);
     302                 :            : 
     303         [ #  # ]:          0 :         if (slot->description)
     304                 :          0 :                 *description = slot->description;
     305         [ #  # ]:          0 :         else if (slot->type == BUS_MATCH_CALLBACK)
     306                 :          0 :                 *description = slot->match_callback.match_string;
     307                 :            :         else
     308                 :          0 :                 return -ENXIO;
     309                 :            : 
     310                 :          0 :         return 0;
     311                 :            : }

Generated by: LCOV version 1.14