Skip to content

Commit

Permalink
refcount: add reference couting utilility macros
Browse files Browse the repository at this point in the history
Co-authored-by: Clemens Famulla-Conrad <cfamullaconrad@suse.de>
  • Loading branch information
mtomaschewski and cfconrad committed Jun 2, 2022
1 parent 68a77fb commit 36febb3
Show file tree
Hide file tree
Showing 4 changed files with 206 additions and 0 deletions.
1 change: 1 addition & 0 deletions include/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ wicked_include_HEADERS = \
wicked/ovs.h \
wicked/pci.h \
wicked/ppp.h \
wicked/refcount.h \
wicked/resolver.h \
wicked/route.h \
wicked/secret.h \
Expand Down
150 changes: 150 additions & 0 deletions include/wicked/refcount.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
/*
* refcount -- reference couting utils
*
* Copyright (C) 2022 SUSE LLC
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Authors:
* Marius Tomaschewski
* Clemens Famulla-Conrad
*/
#ifndef WICKED_REFCOUNT_H
#define WICKED_REFCOUNT_H

#include <wicked/types.h>

typedef unsigned int ni_refcount_t;

extern ni_bool_t ni_refcount_init(ni_refcount_t *refcount);
extern ni_bool_t ni_refcount_increment(ni_refcount_t *refcount);
extern ni_bool_t ni_refcount_decrement(ni_refcount_t *refcount);


#define ni_refcounted_declare_new(prefix,args...) \
prefix##_t * prefix##_new(args)

#define ni_refcounted_declare_ref(prefix) \
prefix##_t * prefix##_ref(prefix##_t *)

#define ni_refcounted_declare_free(prefix) \
void prefix##_free(prefix##_t *)

#define ni_refcounted_declare_hold(prefix) \
ni_bool_t prefix##_hold(prefix##_t **, prefix##_t *)

#define ni_refcounted_declare_drop(prefix) \
ni_bool_t prefix##_drop(prefix##_t **)

#define ni_refcounted_declare_move(prefix) \
ni_bool_t prefix##_move(prefix##_t **, prefix##_t **)


#define ni_refcounted_define_new_xargs(prefix, \
func_args, init_args) \
prefix##_t * \
prefix##_new func_args \
{ \
prefix##_t *obj = malloc(sizeof(*obj)); \
if (obj) { \
if (!prefix##_init init_args) { \
free(obj); \
return NULL; \
} \
if (!ni_refcount_init(&obj->refcount)) { \
prefix##_destroy(obj); \
free(obj); \
return NULL; \
} \
} \
return obj; \
}
#define ni_refcounted_define_new0(prefix) \
ni_refcounted_define_new_xargs(prefix, \
(void), (obj))
#define ni_refcounted_define_new1(prefix, _1) \
ni_refcounted_define_new_xargs(prefix, \
(_1 a), (obj, a))
#define ni_refcounted_define_new2(prefix, _1, _2) \
ni_refcounted_define_new_xargs(prefix, \
(_1 a, _2 b), (obj, a, b))
#define ni_refcounted_define_new3(prefix, _1, _2, _3) \
ni_refcounted_define_new_xargs(prefix, \
(_1 a, _2 b, _3 c), (obj, a, b, c))
#define ni_refcounted_macro(_1, _2, _3, _4, NAME, ...) NAME

#define ni_refcounted_define_new(args...) \
ni_refcounted_macro(args, \
ni_refcounted_define_new3, \
ni_refcounted_define_new2, \
ni_refcounted_define_new1, \
ni_refcounted_define_new0)(args)

#define ni_refcounted_define_ref(prefix) \
prefix##_t * \
prefix##_ref(prefix##_t *ref) \
{ \
if (ref && ni_refcount_increment(&ref->refcount)) \
return ref; \
return NULL; \
}

#define ni_refcounted_define_free(prefix) \
void \
prefix##_free(prefix##_t *ref) \
{ \
if (ref && ni_refcount_decrement(&ref->refcount)) { \
prefix##_destroy(ref); \
free(ref); \
} \
}

#define ni_refcounted_define_hold(prefix) \
ni_bool_t \
prefix##_hold(prefix##_t **tie, prefix##_t *ref) \
{ \
prefix##_t *old; \
if (tie && ref) { \
old = *tie; \
*tie = prefix##_ref(ref); \
prefix##_free(old); \
return TRUE; \
} \
return FALSE; \
}

#define ni_refcounted_define_drop(prefix) \
ni_bool_t \
prefix##_drop(prefix##_t **tie) \
{ \
prefix##_t *old; \
if (tie) { \
old = *tie; \
*tie = NULL; \
prefix##_free(old); \
return TRUE; \
} \
return FALSE; \
}

#define ni_refcounted_define_move(prefix) \
ni_bool_t \
prefix##_move(prefix##_t **dst, prefix##_t **src) \
{ \
if (src && prefix##_hold(dst, *src)) \
return prefix##_drop(src); \
return FALSE; \
}

#endif /* WICKED_REFCOUNT_H */
1 change: 1 addition & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ libwicked_la_SOURCES = \
ppp.c \
pppd.c \
process.c \
refcount.c \
resolver.c \
rfkill.c \
route.c \
Expand Down
54 changes: 54 additions & 0 deletions src/refcount.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* refcount -- reference couting utils
*
* Copyright (C) 2022 SUSE LLC
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Authors:
* Marius Tomaschewski
* Clemens Famulla-Conrad
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <wicked/types.h>
#include <wicked/refcount.h>
#include <wicked/logging.h>

ni_bool_t
ni_refcount_init(ni_refcount_t *refcount)
{
ni_assert(refcount);
*refcount = 1;
return TRUE;
}

ni_bool_t
ni_refcount_increment(ni_refcount_t *refcount)
{
ni_assert(refcount && *refcount);
*refcount += 1;
return *refcount != 0;
}

ni_bool_t
ni_refcount_decrement(ni_refcount_t *refcount)
{
ni_assert(refcount && *refcount);
*refcount -= 1;
return *refcount == 0;
}

0 comments on commit 36febb3

Please sign in to comment.