D-Bus  1.10.12
dbus-resources.c
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 */