Home | History | Annotate | Download | only in dbus
      1 /* -*- mode: C; c-file-style: "gnu" -*- */
      2 /* dbus-resources.c Resource tracking/limits
      3  *
      4  * Copyright (C) 2003  Red Hat Inc.
      5  *
      6  * Licensed under the Academic Free License version 2.1
      7  *
      8  * This program is free software; you can redistribute it and/or modify
      9  * it under the terms of the GNU General Public License as published by
     10  * the Free Software Foundation; either version 2 of the License, or
     11  * (at your option) any later version.
     12  *
     13  * This program is distributed in the hope that it will be useful,
     14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16  * GNU General Public License for more details.
     17  *
     18  * You should have received a copy of the GNU General Public License
     19  * along with this program; if not, write to the Free Software
     20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
     21  *
     22  */
     23 #include <dbus/dbus-resources.h>
     24 #include <dbus/dbus-internals.h>
     25 
     26 /**
     27  * @defgroup DBusResources Resource limits related code
     28  * @ingroup  DBusInternals
     29  * @brief DBusCounter and other stuff related to resource limits
     30  *
     31  * Types and functions related to tracking resource limits,
     32  * such as the maximum amount of memory a connection can use
     33  * for messages, etc.
     34  */
     35 
     36 /**
     37  * @defgroup DBusResourcesInternals Resource limits implementation details
     38  * @ingroup  DBusInternals
     39  * @brief Resource limits implementation details
     40  *
     41  * Implementation details of resource limits code.
     42  *
     43  * @{
     44  */
     45 
     46 /**
     47  * @brief Internals of DBusCounter.
     48  *
     49  * DBusCounter internals. DBusCounter is an opaque object, it must be
     50  * used via accessor functions.
     51  */
     52 struct DBusCounter
     53 {
     54   int refcount;  /**< reference count */
     55 
     56   long value;    /**< current counter value */
     57 
     58   long notify_guard_value; /**< call notify function when crossing this value */
     59   DBusCounterNotifyFunction notify_function; /**< notify function */
     60   void *notify_data; /**< data for notify function */
     61 };
     62 
     63 /** @} */  /* end of resource limits internals docs */
     64 
     65 /**
     66  * @addtogroup DBusResources
     67  * @{
     68  */
     69 
     70 /**
     71  * Creates a new DBusCounter. DBusCounter is used
     72  * to count usage of some resource such as memory.
     73  *
     74  * @returns new counter or #NULL on failure
     75  */
     76 DBusCounter*
     77 _dbus_counter_new (void)
     78 {
     79   DBusCounter *counter;
     80 
     81   counter = dbus_new (DBusCounter, 1);
     82   if (counter == NULL)
     83     return NULL;
     84 
     85   counter->refcount = 1;
     86   counter->value = 0;
     87 
     88   counter->notify_guard_value = 0;
     89   counter->notify_function = NULL;
     90   counter->notify_data = NULL;
     91 
     92   return counter;
     93 }
     94 
     95 /**
     96  * Increments refcount of the counter
     97  *
     98  * @param counter the counter
     99  * @returns the counter
    100  */
    101 DBusCounter *
    102 _dbus_counter_ref (DBusCounter *counter)
    103 {
    104   _dbus_assert (counter->refcount > 0);
    105 
    106   counter->refcount += 1;
    107 
    108   return counter;
    109 }
    110 
    111 /**
    112  * Decrements refcount of the counter and possibly
    113  * finalizes the counter.
    114  *
    115  * @param counter the counter
    116  */
    117 void
    118 _dbus_counter_unref (DBusCounter *counter)
    119 {
    120   _dbus_assert (counter->refcount > 0);
    121 
    122   counter->refcount -= 1;
    123 
    124   if (counter->refcount == 0)
    125     {
    126 
    127       dbus_free (counter);
    128     }
    129 }
    130 
    131 /**
    132  * Adjusts the value of the counter by the given
    133  * delta which may be positive or negative.
    134  * Calls the notify function from _dbus_counter_set_notify()
    135  * if that function has been specified.
    136  *
    137  * @param counter the counter
    138  * @param delta value to add to the counter's current value
    139  */
    140 void
    141 _dbus_counter_adjust (DBusCounter *counter,
    142                       long         delta)
    143 {
    144   long old = counter->value;
    145 
    146   counter->value += delta;
    147 
    148 #if 0
    149   _dbus_verbose ("Adjusting counter %ld by %ld = %ld\n",
    150                  old, delta, counter->value);
    151 #endif
    152 
    153   if (counter->notify_function != NULL &&
    154       ((old < counter->notify_guard_value &&
    155         counter->value >= counter->notify_guard_value) ||
    156        (old >= counter->notify_guard_value &&
    157         counter->value < counter->notify_guard_value)))
    158     (* counter->notify_function) (counter, counter->notify_data);
    159 }
    160 
    161 /**
    162  * Gets the current value of the counter.
    163  *
    164  * @param counter the counter
    165  * @returns its current value
    166  */
    167 long
    168 _dbus_counter_get_value (DBusCounter *counter)
    169 {
    170   return counter->value;
    171 }
    172 
    173 /**
    174  * Sets the notify function for this counter; the notify function is
    175  * called whenever the counter's value crosses the guard value in
    176  * either direction (moving up, or moving down).
    177  *
    178  * @param counter the counter
    179  * @param guard_value the value we're notified if the counter crosses
    180  * @param function function to call in order to notify
    181  * @param user_data data to pass to the function
    182  */
    183 void
    184 _dbus_counter_set_notify (DBusCounter               *counter,
    185                           long                       guard_value,
    186                           DBusCounterNotifyFunction  function,
    187                           void                      *user_data)
    188 {
    189   counter->notify_guard_value = guard_value;
    190   counter->notify_function = function;
    191   counter->notify_data = user_data;
    192 }
    193 
    194 /** @} */  /* end of resource limits exported API */
    195