1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 * 22 */ 23 24 #include <config.h> 25 #include <dbus/dbus-resources.h> 26 #include <dbus/dbus-internals.h> 27 28 /** 29 * @defgroup DBusResources Resource limits related code 30 * @ingroup DBusInternals 31 * @brief DBusCounter and other stuff related to resource limits 32 * 33 * Types and functions related to tracking resource limits, 34 * such as the maximum amount of memory/unix fds a connection can use 35 * for messages, etc. 36 */ 37 38 /** 39 * @defgroup DBusResourcesInternals Resource limits implementation details 40 * @ingroup DBusInternals 41 * @brief Resource limits implementation details 42 * 43 * Implementation details of resource limits code. 44 * 45 * @{ 46 */ 47 48 /** 49 * @brief Internals of DBusCounter. 50 * 51 * DBusCounter internals. DBusCounter is an opaque object, it must be 52 * used via accessor functions. 53 */ 54 struct DBusCounter 55 { 56 int refcount; /**< reference count */ 57 58 long size_value; /**< current size counter value */ 59 long unix_fd_value; /**< current unix fd counter value */ 60 61 long notify_size_guard_value; /**< call notify function when crossing this size value */ 62 long notify_unix_fd_guard_value; /**< call notify function when crossing this unix fd value */ 63 64 DBusCounterNotifyFunction notify_function; /**< notify function */ 65 void *notify_data; /**< data for notify function */ 66 }; 67 68 /** @} */ /* end of resource limits internals docs */ 69 70 /** 71 * @addtogroup DBusResources 72 * @{ 73 */ 74 75 /** 76 * Creates a new DBusCounter. DBusCounter is used 77 * to count usage of some resource such as memory. 78 * 79 * @returns new counter or #NULL on failure 80 */ 81 DBusCounter* 82 _dbus_counter_new (void) 83 { 84 DBusCounter *counter; 85 86 counter = dbus_new (DBusCounter, 1); 87 if (counter == NULL) 88 return NULL; 89 90 counter->refcount = 1; 91 counter->size_value = 0; 92 counter->unix_fd_value = 0; 93 94 counter->notify_size_guard_value = 0; 95 counter->notify_unix_fd_guard_value = 0; 96 counter->notify_function = NULL; 97 counter->notify_data = NULL; 98 99 return counter; 100 } 101 102 /** 103 * Increments refcount of the counter 104 * 105 * @param counter the counter 106 * @returns the counter 107 */ 108 DBusCounter * 109 _dbus_counter_ref (DBusCounter *counter) 110 { 111 _dbus_assert (counter->refcount > 0); 112 113 counter->refcount += 1; 114 115 return counter; 116 } 117 118 /** 119 * Decrements refcount of the counter and possibly 120 * finalizes the counter. 121 * 122 * @param counter the counter 123 */ 124 void 125 _dbus_counter_unref (DBusCounter *counter) 126 { 127 _dbus_assert (counter->refcount > 0); 128 129 counter->refcount -= 1; 130 131 if (counter->refcount == 0) 132 { 133 134 dbus_free (counter); 135 } 136 } 137 138 /** 139 * Adjusts the value of the size counter by the given 140 * delta which may be positive or negative. 141 * Calls the notify function from _dbus_counter_set_notify() 142 * if that function has been specified. 143 * 144 * @param counter the counter 145 * @param delta value to add to the size counter's current value 146 */ 147 void 148 _dbus_counter_adjust_size (DBusCounter *counter, 149 long delta) 150 { 151 long old = counter->size_value; 152 153 counter->size_value += delta; 154 155 #if 0 156 _dbus_verbose ("Adjusting counter %ld by %ld = %ld\n", 157 old, delta, counter->size_value); 158 #endif 159 160 if (counter->notify_function != NULL && 161 ((old < counter->notify_size_guard_value && 162 counter->size_value >= counter->notify_size_guard_value) || 163 (old >= counter->notify_size_guard_value && 164 counter->size_value < counter->notify_size_guard_value))) 165 (* counter->notify_function) (counter, counter->notify_data); 166 } 167 168 /** 169 * Adjusts the value of the unix fd counter by the given 170 * delta which may be positive or negative. 171 * Calls the notify function from _dbus_counter_set_notify() 172 * if that function has been specified. 173 * 174 * @param counter the counter 175 * @param delta value to add to the unix fds counter's current value 176 */ 177 void 178 _dbus_counter_adjust_unix_fd (DBusCounter *counter, 179 long delta) 180 { 181 long old = counter->unix_fd_value; 182 183 counter->unix_fd_value += delta; 184 185 #if 0 186 _dbus_verbose ("Adjusting counter %ld by %ld = %ld\n", 187 old, delta, counter->unix_fd_value); 188 #endif 189 190 if (counter->notify_function != NULL && 191 ((old < counter->notify_unix_fd_guard_value && 192 counter->unix_fd_value >= counter->notify_unix_fd_guard_value) || 193 (old >= counter->notify_unix_fd_guard_value && 194 counter->unix_fd_value < counter->notify_unix_fd_guard_value))) 195 (* counter->notify_function) (counter, counter->notify_data); 196 } 197 198 /** 199 * Gets the current value of the size counter. 200 * 201 * @param counter the counter 202 * @returns its current size value 203 */ 204 long 205 _dbus_counter_get_size_value (DBusCounter *counter) 206 { 207 return counter->size_value; 208 } 209 210 /** 211 * Gets the current value of the unix fd counter. 212 * 213 * @param counter the counter 214 * @returns its current unix fd value 215 */ 216 long 217 _dbus_counter_get_unix_fd_value (DBusCounter *counter) 218 { 219 return counter->unix_fd_value; 220 } 221 222 /** 223 * Sets the notify function for this counter; the notify function is 224 * called whenever the counter's values cross the guard values in 225 * either direction (moving up, or moving down). 226 * 227 * @param counter the counter 228 * @param size_guard_value the value we're notified if the size counter crosses 229 * @param unix_fd_guard_value the value we're notified if the unix fd counter crosses 230 * @param function function to call in order to notify 231 * @param user_data data to pass to the function 232 */ 233 void 234 _dbus_counter_set_notify (DBusCounter *counter, 235 long size_guard_value, 236 long unix_fd_guard_value, 237 DBusCounterNotifyFunction function, 238 void *user_data) 239 { 240 counter->notify_size_guard_value = size_guard_value; 241 counter->notify_unix_fd_guard_value = unix_fd_guard_value; 242 counter->notify_function = function; 243 counter->notify_data = user_data; 244 } 245 246 /** @} */ /* end of resource limits exported API */ 247