D-Bus
1.10.12
|
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 00002 /* dbus-resources.c Resource tracking/limits 00003 * 00004 * Copyright (C) 2003 Red Hat Inc. 00005 * 00006 * Licensed under the Academic Free License version 2.1 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License 00019 * along with this program; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 * 00022 */ 00023 00024 #include <config.h> 00025 #include <dbus/dbus-resources.h> 00026 #include <dbus/dbus-internals.h> 00027 00054 struct DBusCounter 00055 { 00056 int refcount; 00058 long size_value; 00059 long unix_fd_value; 00061 #ifdef DBUS_ENABLE_STATS 00062 long peak_size_value; 00063 long peak_unix_fd_value; 00064 #endif 00065 00066 long notify_size_guard_value; 00067 long notify_unix_fd_guard_value; 00069 DBusCounterNotifyFunction notify_function; 00070 void *notify_data; 00071 dbus_bool_t notify_pending : 1; 00072 DBusRMutex *mutex; 00073 }; 00074 /* end of resource limits internals docs */ 00076 00088 DBusCounter* 00089 _dbus_counter_new (void) 00090 { 00091 DBusCounter *counter; 00092 00093 counter = dbus_new0 (DBusCounter, 1); 00094 if (counter == NULL) 00095 return NULL; 00096 00097 counter->refcount = 1; 00098 00099 _dbus_rmutex_new_at_location (&counter->mutex); 00100 if (counter->mutex == NULL) 00101 { 00102 dbus_free (counter); 00103 counter = NULL; 00104 } 00105 00106 return counter; 00107 } 00108 00115 DBusCounter * 00116 _dbus_counter_ref (DBusCounter *counter) 00117 { 00118 _dbus_rmutex_lock (counter->mutex); 00119 00120 _dbus_assert (counter->refcount > 0); 00121 00122 counter->refcount += 1; 00123 00124 _dbus_rmutex_unlock (counter->mutex); 00125 00126 return counter; 00127 } 00128 00135 void 00136 _dbus_counter_unref (DBusCounter *counter) 00137 { 00138 dbus_bool_t last_ref = FALSE; 00139 00140 _dbus_rmutex_lock (counter->mutex); 00141 00142 _dbus_assert (counter->refcount > 0); 00143 00144 counter->refcount -= 1; 00145 last_ref = (counter->refcount == 0); 00146 00147 _dbus_rmutex_unlock (counter->mutex); 00148 00149 if (last_ref) 00150 { 00151 _dbus_rmutex_free_at_location (&counter->mutex); 00152 dbus_free (counter); 00153 } 00154 } 00155 00166 void 00167 _dbus_counter_adjust_size (DBusCounter *counter, 00168 long delta) 00169 { 00170 long old = 0; 00171 00172 _dbus_rmutex_lock (counter->mutex); 00173 00174 old = counter->size_value; 00175 00176 counter->size_value += delta; 00177 00178 #ifdef DBUS_ENABLE_STATS 00179 if (counter->peak_size_value < counter->size_value) 00180 counter->peak_size_value = counter->size_value; 00181 #endif 00182 00183 #if 0 00184 _dbus_verbose ("Adjusting counter %ld by %ld = %ld\n", 00185 old, delta, counter->size_value); 00186 #endif 00187 00188 if (counter->notify_function != NULL && 00189 ((old < counter->notify_size_guard_value && 00190 counter->size_value >= counter->notify_size_guard_value) || 00191 (old >= counter->notify_size_guard_value && 00192 counter->size_value < counter->notify_size_guard_value))) 00193 counter->notify_pending = TRUE; 00194 00195 _dbus_rmutex_unlock (counter->mutex); 00196 } 00197 00206 void 00207 _dbus_counter_notify (DBusCounter *counter) 00208 { 00209 DBusCounterNotifyFunction notify_function = NULL; 00210 void *notify_data = NULL; 00211 00212 _dbus_rmutex_lock (counter->mutex); 00213 if (counter->notify_pending) 00214 { 00215 counter->notify_pending = FALSE; 00216 notify_function = counter->notify_function; 00217 notify_data = counter->notify_data; 00218 } 00219 _dbus_rmutex_unlock (counter->mutex); 00220 00221 if (notify_function != NULL) 00222 (* notify_function) (counter, notify_data); 00223 } 00224 00235 void 00236 _dbus_counter_adjust_unix_fd (DBusCounter *counter, 00237 long delta) 00238 { 00239 long old = 0; 00240 00241 _dbus_rmutex_lock (counter->mutex); 00242 00243 old = counter->unix_fd_value; 00244 00245 counter->unix_fd_value += delta; 00246 00247 #ifdef DBUS_ENABLE_STATS 00248 if (counter->peak_unix_fd_value < counter->unix_fd_value) 00249 counter->peak_unix_fd_value = counter->unix_fd_value; 00250 #endif 00251 00252 #if 0 00253 _dbus_verbose ("Adjusting counter %ld by %ld = %ld\n", 00254 old, delta, counter->unix_fd_value); 00255 #endif 00256 00257 if (counter->notify_function != NULL && 00258 ((old < counter->notify_unix_fd_guard_value && 00259 counter->unix_fd_value >= counter->notify_unix_fd_guard_value) || 00260 (old >= counter->notify_unix_fd_guard_value && 00261 counter->unix_fd_value < counter->notify_unix_fd_guard_value))) 00262 counter->notify_pending = TRUE; 00263 00264 _dbus_rmutex_unlock (counter->mutex); 00265 } 00266 00273 long 00274 _dbus_counter_get_size_value (DBusCounter *counter) 00275 { 00276 return counter->size_value; 00277 } 00278 00285 long 00286 _dbus_counter_get_unix_fd_value (DBusCounter *counter) 00287 { 00288 return counter->unix_fd_value; 00289 } 00290 00302 void 00303 _dbus_counter_set_notify (DBusCounter *counter, 00304 long size_guard_value, 00305 long unix_fd_guard_value, 00306 DBusCounterNotifyFunction function, 00307 void *user_data) 00308 { 00309 _dbus_rmutex_lock (counter->mutex); 00310 counter->notify_size_guard_value = size_guard_value; 00311 counter->notify_unix_fd_guard_value = unix_fd_guard_value; 00312 counter->notify_function = function; 00313 counter->notify_data = user_data; 00314 counter->notify_pending = FALSE; 00315 _dbus_rmutex_unlock (counter->mutex); 00316 } 00317 00318 #ifdef DBUS_ENABLE_STATS 00319 long 00320 _dbus_counter_get_peak_size_value (DBusCounter *counter) 00321 { 00322 return counter->peak_size_value; 00323 } 00324 00325 long 00326 _dbus_counter_get_peak_unix_fd_value (DBusCounter *counter) 00327 { 00328 return counter->peak_unix_fd_value; 00329 } 00330 #endif 00331 /* end of resource limits exported API */