Merge branch 'dbus-1.2'
[platform/upstream/dbus.git] / dbus / dbus-resources.c
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 #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/unix fds 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 size_value;       /**< current size counter value */
57   long unix_fd_value;    /**< current unix fd counter value */
58
59   long notify_size_guard_value;    /**< call notify function when crossing this size value */
60   long notify_unix_fd_guard_value; /**< call notify function when crossing this unix fd value */
61
62   DBusCounterNotifyFunction notify_function; /**< notify function */
63   void *notify_data; /**< data for notify function */
64 };
65
66 /** @} */  /* end of resource limits internals docs */
67
68 /**
69  * @addtogroup DBusResources
70  * @{
71  */
72
73 /**
74  * Creates a new DBusCounter. DBusCounter is used
75  * to count usage of some resource such as memory.
76  *
77  * @returns new counter or #NULL on failure
78  */
79 DBusCounter*
80 _dbus_counter_new (void)
81 {
82   DBusCounter *counter;
83
84   counter = dbus_new (DBusCounter, 1);
85   if (counter == NULL)
86     return NULL;
87   
88   counter->refcount = 1;
89   counter->size_value = 0;
90   counter->unix_fd_value = 0;
91
92   counter->notify_size_guard_value = 0;
93   counter->notify_unix_fd_guard_value = 0;
94   counter->notify_function = NULL;
95   counter->notify_data = NULL;
96   
97   return counter;
98 }
99
100 /**
101  * Increments refcount of the counter
102  *
103  * @param counter the counter
104  * @returns the counter
105  */
106 DBusCounter *
107 _dbus_counter_ref (DBusCounter *counter)
108 {
109   _dbus_assert (counter->refcount > 0);
110   
111   counter->refcount += 1;
112
113   return counter;
114 }
115
116 /**
117  * Decrements refcount of the counter and possibly
118  * finalizes the counter.
119  *
120  * @param counter the counter
121  */
122 void
123 _dbus_counter_unref (DBusCounter *counter)
124 {
125   _dbus_assert (counter->refcount > 0);
126
127   counter->refcount -= 1;
128
129   if (counter->refcount == 0)
130     {
131       
132       dbus_free (counter);
133     }
134 }
135
136 /**
137  * Adjusts the value of the size counter by the given
138  * delta which may be positive or negative.
139  * Calls the notify function from _dbus_counter_set_notify()
140  * if that function has been specified.
141  *
142  * @param counter the counter
143  * @param delta value to add to the size counter's current value
144  */
145 void
146 _dbus_counter_adjust_size (DBusCounter *counter,
147                            long         delta)
148 {
149   long old = counter->size_value;
150
151   counter->size_value += delta;
152
153 #if 0
154   _dbus_verbose ("Adjusting counter %ld by %ld = %ld\n",
155                  old, delta, counter->size_value);
156 #endif
157
158   if (counter->notify_function != NULL &&
159       ((old < counter->notify_size_guard_value &&
160         counter->size_value >= counter->notify_size_guard_value) ||
161        (old >= counter->notify_size_guard_value &&
162         counter->size_value < counter->notify_size_guard_value)))
163     (* counter->notify_function) (counter, counter->notify_data);
164 }
165
166 /**
167  * Adjusts the value of the unix fd counter by the given
168  * delta which may be positive or negative.
169  * Calls the notify function from _dbus_counter_set_notify()
170  * if that function has been specified.
171  *
172  * @param counter the counter
173  * @param delta value to add to the unix fds counter's current value
174  */
175 void
176 _dbus_counter_adjust_unix_fd (DBusCounter *counter,
177                               long         delta)
178 {
179   long old = counter->unix_fd_value;
180   
181   counter->unix_fd_value += delta;
182
183 #if 0
184   _dbus_verbose ("Adjusting counter %ld by %ld = %ld\n",
185                  old, delta, counter->unix_fd_value);
186 #endif
187   
188   if (counter->notify_function != NULL &&
189       ((old < counter->notify_unix_fd_guard_value &&
190         counter->unix_fd_value >= counter->notify_unix_fd_guard_value) ||
191        (old >= counter->notify_unix_fd_guard_value &&
192         counter->unix_fd_value < counter->notify_unix_fd_guard_value)))
193     (* counter->notify_function) (counter, counter->notify_data);
194 }
195
196 /**
197  * Gets the current value of the size counter.
198  *
199  * @param counter the counter
200  * @returns its current size value
201  */
202 long
203 _dbus_counter_get_size_value (DBusCounter *counter)
204 {
205   return counter->size_value;
206 }
207
208 /**
209  * Gets the current value of the unix fd counter.
210  *
211  * @param counter the counter
212  * @returns its current unix fd value
213  */
214 long
215 _dbus_counter_get_unix_fd_value (DBusCounter *counter)
216 {
217   return counter->unix_fd_value;
218 }
219
220 /**
221  * Sets the notify function for this counter; the notify function is
222  * called whenever the counter's values cross the guard values in
223  * either direction (moving up, or moving down).
224  *
225  * @param counter the counter
226  * @param size_guard_value the value we're notified if the size counter crosses
227  * @param unix_fd_guard_value the value we're notified if the unix fd counter crosses
228  * @param function function to call in order to notify
229  * @param user_data data to pass to the function
230  */
231 void
232 _dbus_counter_set_notify (DBusCounter               *counter,
233                           long                       size_guard_value,
234                           long                       unix_fd_guard_value,
235                           DBusCounterNotifyFunction  function,
236                           void                      *user_data)
237 {
238   counter->notify_size_guard_value = size_guard_value;
239   counter->notify_unix_fd_guard_value = unix_fd_guard_value;
240   counter->notify_function = function;
241   counter->notify_data = user_data;
242 }
243
244 /** @} */  /* end of resource limits exported API */