LCOV - code coverage report
Current view: top level - libsystemd/sd-bus - bus-slot.c (source / functions) Hit Total Coverage
Test: systemd test coverage Lines: 83 130 63.8 %
Date: 2015-07-29 18:47:03 Functions: 4 12 33.3 %

          Line data    Source code
       1             : /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
       2             : 
       3             : /***
       4             :   This file is part of systemd.
       5             : 
       6             :   Copyright 2013 Lennart Poettering
       7             : 
       8             :   systemd is free software; you can redistribute it and/or modify it
       9             :   under the terms of the GNU Lesser General Public License as published by
      10             :   the Free Software Foundation; either version 2.1 of the License, or
      11             :   (at your option) any later version.
      12             : 
      13             :   systemd is distributed in the hope that it will be useful, but
      14             :   WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
      16             :   Lesser General Public License for more details.
      17             : 
      18             :   You should have received a copy of the GNU Lesser General Public License
      19             :   along with systemd; If not, see <http://www.gnu.org/licenses/>.
      20             : ***/
      21             : 
      22             : #include "sd-bus.h"
      23             : #include "bus-control.h"
      24             : #include "bus-objects.h"
      25             : #include "bus-slot.h"
      26             : 
      27          45 : sd_bus_slot *bus_slot_allocate(
      28             :                 sd_bus *bus,
      29             :                 bool floating,
      30             :                 BusSlotType type,
      31             :                 size_t extra,
      32             :                 void *userdata) {
      33             : 
      34             :         sd_bus_slot *slot;
      35             : 
      36          45 :         assert(bus);
      37             : 
      38          45 :         slot = malloc0(offsetof(sd_bus_slot, reply_callback) + extra);
      39          45 :         if (!slot)
      40           0 :                 return NULL;
      41             : 
      42          45 :         slot->n_ref = 1;
      43          45 :         slot->type = type;
      44          45 :         slot->bus = bus;
      45          45 :         slot->floating = floating;
      46          45 :         slot->userdata = userdata;
      47             : 
      48          45 :         if (!floating)
      49           0 :                 sd_bus_ref(bus);
      50             : 
      51          45 :         LIST_PREPEND(slots, bus->slots, slot);
      52             : 
      53          45 :         return slot;
      54             : }
      55             : 
      56          71 : _public_ sd_bus_slot* sd_bus_slot_ref(sd_bus_slot *slot) {
      57          71 :         assert_return(slot, NULL);
      58             : 
      59          71 :         assert(slot->n_ref > 0);
      60             : 
      61          71 :         slot->n_ref++;
      62          71 :         return slot;
      63             : }
      64             : 
      65          90 : void bus_slot_disconnect(sd_bus_slot *slot) {
      66             :         sd_bus *bus;
      67             : 
      68          90 :         assert(slot);
      69             : 
      70          90 :         if (!slot->bus)
      71          45 :                 return;
      72             : 
      73          45 :         switch (slot->type) {
      74             : 
      75             :         case BUS_REPLY_CALLBACK:
      76             : 
      77           2 :                 if (slot->reply_callback.cookie != 0)
      78           0 :                         ordered_hashmap_remove(slot->bus->reply_callbacks, &slot->reply_callback.cookie);
      79             : 
      80           2 :                 if (slot->reply_callback.timeout != 0)
      81           0 :                         prioq_remove(slot->bus->reply_callbacks_prioq, &slot->reply_callback, &slot->reply_callback.prioq_idx);
      82             : 
      83           2 :                 break;
      84             : 
      85             :         case BUS_FILTER_CALLBACK:
      86           0 :                 slot->bus->filter_callbacks_modified = true;
      87           0 :                 LIST_REMOVE(callbacks, slot->bus->filter_callbacks, &slot->filter_callback);
      88           0 :                 break;
      89             : 
      90             :         case BUS_MATCH_CALLBACK:
      91             : 
      92          35 :                 if (slot->match_added)
      93          35 :                         bus_remove_match_internal(slot->bus, slot->match_callback.match_string, slot->match_callback.cookie);
      94             : 
      95          35 :                 slot->bus->match_callbacks_modified = true;
      96          35 :                 bus_match_remove(&slot->bus->match_callbacks, &slot->match_callback);
      97             : 
      98          35 :                 free(slot->match_callback.match_string);
      99             : 
     100          35 :                 break;
     101             : 
     102             :         case BUS_NODE_CALLBACK:
     103             : 
     104           1 :                 if (slot->node_callback.node) {
     105           1 :                         LIST_REMOVE(callbacks, slot->node_callback.node->callbacks, &slot->node_callback);
     106           1 :                         slot->bus->nodes_modified = true;
     107             : 
     108           1 :                         bus_node_gc(slot->bus, slot->node_callback.node);
     109             :                 }
     110             : 
     111           1 :                 break;
     112             : 
     113             :         case BUS_NODE_ENUMERATOR:
     114             : 
     115           2 :                 if (slot->node_enumerator.node) {
     116           2 :                         LIST_REMOVE(enumerators, slot->node_enumerator.node->enumerators, &slot->node_enumerator);
     117           2 :                         slot->bus->nodes_modified = true;
     118             : 
     119           2 :                         bus_node_gc(slot->bus, slot->node_enumerator.node);
     120             :                 }
     121             : 
     122           2 :                 break;
     123             : 
     124             :         case BUS_NODE_OBJECT_MANAGER:
     125             : 
     126           2 :                 if (slot->node_object_manager.node) {
     127           2 :                         LIST_REMOVE(object_managers, slot->node_object_manager.node->object_managers, &slot->node_object_manager);
     128           2 :                         slot->bus->nodes_modified = true;
     129             : 
     130           2 :                         bus_node_gc(slot->bus, slot->node_object_manager.node);
     131             :                 }
     132             : 
     133           2 :                 break;
     134             : 
     135             :         case BUS_NODE_VTABLE:
     136             : 
     137           3 :                 if (slot->node_vtable.node && slot->node_vtable.interface && slot->node_vtable.vtable) {
     138             :                         const sd_bus_vtable *v;
     139             : 
     140          32 :                         for (v = slot->node_vtable.vtable; v->type != _SD_BUS_VTABLE_END; v++) {
     141          29 :                                 struct vtable_member *x = NULL;
     142             : 
     143          29 :                                 switch (v->type) {
     144             : 
     145             :                                 case _SD_BUS_VTABLE_METHOD: {
     146             :                                         struct vtable_member key;
     147             : 
     148          16 :                                         key.path = slot->node_vtable.node->path;
     149          16 :                                         key.interface = slot->node_vtable.interface;
     150          16 :                                         key.member = v->x.method.member;
     151             : 
     152          16 :                                         x = hashmap_remove(slot->bus->vtable_methods, &key);
     153          16 :                                         break;
     154             :                                 }
     155             : 
     156             :                                 case _SD_BUS_VTABLE_PROPERTY:
     157             :                                 case _SD_BUS_VTABLE_WRITABLE_PROPERTY: {
     158             :                                         struct vtable_member key;
     159             : 
     160          10 :                                         key.path = slot->node_vtable.node->path;
     161          10 :                                         key.interface = slot->node_vtable.interface;
     162          10 :                                         key.member = v->x.method.member;
     163             : 
     164             : 
     165          10 :                                         x = hashmap_remove(slot->bus->vtable_properties, &key);
     166          10 :                                         break;
     167             :                                 }}
     168             : 
     169          29 :                                 free(x);
     170             :                         }
     171             :                 }
     172             : 
     173           3 :                 free(slot->node_vtable.interface);
     174             : 
     175           3 :                 if (slot->node_vtable.node) {
     176           3 :                         LIST_REMOVE(vtables, slot->node_vtable.node->vtables, &slot->node_vtable);
     177           3 :                         slot->bus->nodes_modified = true;
     178             : 
     179           3 :                         bus_node_gc(slot->bus, slot->node_vtable.node);
     180             :                 }
     181             : 
     182           3 :                 break;
     183             : 
     184             :         default:
     185           0 :                 assert_not_reached("Wut? Unknown slot type?");
     186             :         }
     187             : 
     188          45 :         bus = slot->bus;
     189             : 
     190          45 :         slot->type = _BUS_SLOT_INVALID;
     191          45 :         slot->bus = NULL;
     192          45 :         LIST_REMOVE(slots, bus->slots, slot);
     193             : 
     194          45 :         if (!slot->floating)
     195           0 :                 sd_bus_unref(bus);
     196             : }
     197             : 
     198         152 : _public_ sd_bus_slot* sd_bus_slot_unref(sd_bus_slot *slot) {
     199             : 
     200         152 :         if (!slot)
     201          36 :                 return NULL;
     202             : 
     203         116 :         assert(slot->n_ref > 0);
     204             : 
     205         116 :         if (slot->n_ref > 1) {
     206          71 :                 slot->n_ref --;
     207          71 :                 return NULL;
     208             :         }
     209             : 
     210          45 :         bus_slot_disconnect(slot);
     211          45 :         free(slot->description);
     212          45 :         free(slot);
     213             : 
     214          45 :         return NULL;
     215             : }
     216             : 
     217           0 : _public_ sd_bus* sd_bus_slot_get_bus(sd_bus_slot *slot) {
     218           0 :         assert_return(slot, NULL);
     219             : 
     220           0 :         return slot->bus;
     221             : }
     222             : 
     223           0 : _public_ void *sd_bus_slot_get_userdata(sd_bus_slot *slot) {
     224           0 :         assert_return(slot, NULL);
     225             : 
     226           0 :         return slot->userdata;
     227             : }
     228             : 
     229           0 : _public_ void *sd_bus_slot_set_userdata(sd_bus_slot *slot, void *userdata) {
     230             :         void *ret;
     231             : 
     232           0 :         assert_return(slot, NULL);
     233             : 
     234           0 :         ret = slot->userdata;
     235           0 :         slot->userdata = userdata;
     236             : 
     237           0 :         return ret;
     238             : }
     239             : 
     240           0 : _public_ sd_bus_message *sd_bus_slot_get_current_message(sd_bus_slot *slot) {
     241           0 :         assert_return(slot, NULL);
     242           0 :         assert_return(slot->type >= 0, NULL);
     243             : 
     244           0 :         if (slot->bus->current_slot != slot)
     245           0 :                 return NULL;
     246             : 
     247           0 :         return slot->bus->current_message;
     248             : }
     249             : 
     250           0 : _public_ sd_bus_message_handler_t sd_bus_slot_get_current_handler(sd_bus_slot *slot) {
     251           0 :         assert_return(slot, NULL);
     252           0 :         assert_return(slot->type >= 0, NULL);
     253             : 
     254           0 :         if (slot->bus->current_slot != slot)
     255           0 :                 return NULL;
     256             : 
     257           0 :         return slot->bus->current_handler;
     258             : }
     259             : 
     260           0 : _public_ void* sd_bus_slot_get_current_userdata(sd_bus_slot *slot) {
     261           0 :         assert_return(slot, NULL);
     262           0 :         assert_return(slot->type >= 0, NULL);
     263             : 
     264           0 :         if (slot->bus->current_slot != slot)
     265           0 :                 return NULL;
     266             : 
     267           0 :         return slot->bus->current_userdata;
     268             : }
     269             : 
     270           0 : _public_ int sd_bus_slot_set_description(sd_bus_slot *slot, const char *description) {
     271           0 :         assert_return(slot, -EINVAL);
     272             : 
     273           0 :         return free_and_strdup(&slot->description, description);
     274             : }
     275             : 
     276           0 : _public_ int sd_bus_slot_get_description(sd_bus_slot *slot, const char **description) {
     277           0 :         assert_return(slot, -EINVAL);
     278           0 :         assert_return(description, -EINVAL);
     279           0 :         assert_return(slot->description, -ENXIO);
     280             : 
     281           0 :         *description = slot->description;
     282           0 :         return 0;
     283             : }

Generated by: LCOV version 1.11