/build/buildd/libnl-1.0~pre6/lib/object.c

00001 /*
00002  * lib/object.c         Generic Cacheable Object
00003  *
00004  *      This library is free software; you can redistribute it and/or
00005  *      modify it under the terms of the GNU Lesser General Public
00006  *      License as published by the Free Software Foundation version 2.1
00007  *      of the License.
00008  *
00009  * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
00010  */
00011 
00012 /**
00013  * @ingroup cache
00014  * @defgroup object Cacheable Object
00015  * @{
00016  */
00017 
00018 #include <netlink-local.h>
00019 #include <netlink/netlink.h>
00020 #include <netlink/cache.h>
00021 #include <netlink/object.h>
00022 #include <netlink/utils.h>
00023 
00024 static inline struct nl_cache_ops *obj_ops(struct nl_object *obj)
00025 {
00026         if (!obj->ce_ops)
00027                 BUG();
00028 
00029         return obj->ce_ops;
00030 }
00031 
00032 /**
00033  * @name Object Creation/Deletion
00034  * @{
00035  */
00036 
00037 /**
00038  * Allocate a cacheable object
00039  * @arg size            size of object
00040  * @return The new object or NULL.
00041  */
00042 struct nl_object *nl_object_alloc(size_t size)
00043 {
00044         struct nl_object *new;
00045 
00046         if (size < sizeof(*new))
00047                 BUG();
00048 
00049         new = calloc(1, size);
00050         if (!new) {
00051                 nl_errno(ENOMEM);
00052                 return NULL;
00053         }
00054 
00055         new->ce_refcnt = 1;
00056         nl_init_list_head(&new->ce_list);
00057 
00058         return new;
00059 }
00060 
00061 /**
00062  * Allocate a new object of kind specified by the operations handle
00063  * @arg ops             cache operations handle
00064  * @return The new object or NULL
00065  */
00066 struct nl_object *nl_object_alloc_from_ops(struct nl_cache_ops *ops)
00067 {
00068         struct nl_object *new;
00069 
00070         new = nl_object_alloc(ops->co_size);
00071         if (new) {
00072                 new->ce_ops = ops;
00073                 if (ops->co_constructor)
00074                         ops->co_constructor(new);
00075         }
00076 
00077         return new;
00078 }
00079 
00080 /**
00081  * Allocate a new object of kind specified by the name
00082  * @arg kind            name of object type
00083  * @return The new object or nULL
00084  */
00085 struct nl_object *nl_object_alloc_name(const char *kind)
00086 {
00087         struct nl_cache_ops *ops;
00088 
00089         ops = nl_cache_mngt_lookup(kind);
00090         if (!ops) {
00091                 nl_error(ENOENT, "Unable to lookup cache kind \"%s\"", kind);
00092                 return NULL;
00093         }
00094 
00095         return nl_object_alloc_from_ops(ops);
00096 }
00097 
00098 struct nl_derived_object {
00099         NLHDR_COMMON
00100         char data;
00101 };
00102 
00103 /**
00104  * Allocate a new object and copy all data from an existing object
00105  * @arg obj             object to inherite data from
00106  * @return The new object or NULL.
00107  */
00108 struct nl_object *nl_object_clone(struct nl_object *obj)
00109 {
00110         struct nl_object *new;
00111         struct nl_cache_ops *ops = obj_ops(obj);
00112         int doff = offsetof(struct nl_derived_object, data);
00113         int size;
00114 
00115         new = nl_object_alloc(ops->co_size);
00116         if (!new)
00117                 return NULL;
00118 
00119         size = ops->co_size - doff;
00120         if (size < 0)
00121                 BUG();
00122 
00123         new->ce_cache = obj->ce_cache;
00124         new->ce_ops = obj->ce_ops;
00125         new->ce_msgtype = obj->ce_msgtype;
00126         if (ops->co_free_data) {
00127                 new->ce_dataref = obj;
00128                 nl_object_get(obj);
00129         }
00130 
00131         if (size)
00132                 memcpy((void *)new + doff, (void *)obj + doff, size);
00133 
00134         return new;
00135 }
00136 
00137 /**
00138  * Free a cacheable object
00139  * @arg obj             object to free
00140  *
00141  * @return 0 or a negative error code.
00142  */
00143 void nl_object_free(struct nl_object *obj)
00144 {
00145         struct nl_cache_ops *ops = obj_ops(obj);
00146 
00147         if (obj->ce_refcnt > 0)
00148                 NL_DBG(1, "Warning: Freeing object in used...\n");
00149 
00150         if (obj->ce_dataref)
00151                 nl_object_put(obj->ce_dataref);
00152         else if (ops->co_free_data)
00153                 ops->co_free_data(obj);
00154 
00155         free(obj);
00156 }
00157 
00158 /** @} */
00159 
00160 /**
00161  * @name Reference Management
00162  * @{
00163  */
00164 
00165 /**
00166  * Acquire a reference on a object
00167  * @arg obj             object to acquire reference from
00168  */
00169 void nl_object_get(struct nl_object *obj)
00170 {
00171         obj->ce_refcnt++;
00172 }
00173 
00174 /**
00175  * Release a reference from an object
00176  * @arg obj             object to release reference from
00177  */
00178 void nl_object_put(struct nl_object *obj)
00179 {
00180         if (!obj)
00181                 return;
00182 
00183         obj->ce_refcnt--;
00184 
00185         if (obj->ce_refcnt < 0)
00186                 BUG();
00187 
00188         if (obj->ce_refcnt <= 0)
00189                 nl_object_free(obj);
00190 }
00191 
00192 /**
00193  * Check whether this object is used by multiple users
00194  * @arg obj             object to check
00195  * @return true or false
00196  */
00197 int nl_object_shared(struct nl_object *obj)
00198 {
00199         return obj->ce_refcnt > 1;
00200 }
00201 
00202 /** @} */
00203 
00204 /**
00205  * @name Utillities
00206  * @{
00207  */
00208 
00209 /**
00210  * Dump this object according to the specified parameters
00211  * @arg obj             object to dump
00212  * @arg params          dumping parameters
00213  */
00214 void nl_object_dump(struct nl_object *obj, struct nl_dump_params *params)
00215 {
00216         dump_from_ops(obj, params);
00217 }
00218 
00219 /**
00220  * Match a filter against an object
00221  * @arg obj             object to check
00222  * @arg filter          filter object
00223  *
00224  * @return 0 if the object matches the filter or non-zero
00225  *           if no filter procedure is available or if the
00226  *           filter does not match.
00227  */
00228 int nl_object_match(struct nl_object *obj, struct nl_object *filter)
00229 {
00230         struct nl_cache_ops *ops = obj->ce_ops;
00231 
00232         if (ops == filter->ce_ops &&
00233             ops->co_filter && !ops->co_filter(obj, filter))
00234                 return 1;
00235         else
00236                 return 0;
00237 }
00238 
00239 /** @} */
00240 
00241 /**
00242  * @name Access Functions
00243  * @{
00244  */
00245 
00246 /**
00247  * Get reference count of object
00248  * @arg obj             object handle
00249  */
00250 int nl_object_get_refcnt(struct nl_object *obj)
00251 {
00252         return obj->ce_refcnt;
00253 }
00254 
00255 /**
00256  * Get cache operations of object
00257  * @arg obj             object handle
00258  */
00259 struct nl_cache_ops *nl_object_get_ops(struct nl_object *obj)
00260 {
00261         return obj->ce_ops;
00262 }
00263 
00264 /**
00265  * Get cache this object is in
00266  * @arg obj             object handle
00267  * @return cache handle or NULL if object is not associated to a cache
00268  */
00269 struct nl_cache *nl_object_get_cache(struct nl_object *obj)
00270 {
00271         return obj->ce_cache;
00272 }
00273 
00274 /**
00275  * Get the private data of object
00276  * @arg obj             object handle
00277  */
00278 inline void *nl_object_priv(struct nl_object *obj)
00279 {
00280         return obj;
00281 }
00282 
00283 /** @} */
00284 
00285 /** @} */

Generated on Fri Apr 27 14:14:07 2007 for libnl by  doxygen 1.5.1