00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
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