libkeepalive
Loading...
Searching...
No Matches
keepalive-object.h File Reference

Provides common base for locking and reference counting. More...

#include <stdarg.h>
#include <stdbool.h>
#include <glib.h>
#include <dbus/dbus.h>

Go to the source code of this file.

Data Structures

struct  keepalive_object_t
 

Typedefs

typedef struct keepalive_object_t keepalive_object_t
 

Functions

void keepalive_object_ctor (keepalive_object_t *self, const char *identity, GDestroyNotify shutdown_locked_cb, GDestroyNotify delete_cb)
 
void keepalive_object_dtor (keepalive_object_t *self)
 
void keepalive_object_lock (keepalive_object_t *self)
 
void keepalive_object_unlock (keepalive_object_t *self)
 
void * keepalive_object_ref_external_locked (keepalive_object_t *self)
 
void * keepalive_object_ref_internal_locked (keepalive_object_t *self)
 
void keepalive_object_unref_external_locked (keepalive_object_t *self)
 
void keepalive_object_unref_internal_locked (keepalive_object_t *self)
 
void keepalive_object_unref_internal_cb (void *aptr)
 
void keepalive_object_timer_start_locked (keepalive_object_t *self, guint *timer_id, guint interval, GSourceFunc notify_cb)
 
void keepalive_object_timer_stop_locked (keepalive_object_t *self, guint *timer_id)
 
bool keepalive_object_in_shutdown_locked (keepalive_object_t *self)
 
void keepalive_object_ipc_start_locked_va (keepalive_object_t *self, DBusPendingCall **where, DBusPendingCallNotifyFunction notify_cb, DBusConnection *connection, const char *service, const char *object, const char *interface, const char *method, int arg_type, va_list va)
 
void keepalive_object_ipc_cancel_locked (keepalive_object_t *self, DBusPendingCall **where)
 
bool keepalive_object_ipc_finish_locked (keepalive_object_t *self, DBusPendingCall **where, DBusPendingCall *what)
 
void keepalive_object_iowatch_start_locked (keepalive_object_t *self, guint *iowatch_id, int fd, GIOCondition cnd, GIOFunc io_cb)
 
void keepalive_object_iowatch_stop_locked (keepalive_object_t *self, guint *iowatch_id)
 

Detailed Description

Provides common base for locking and reference counting.

Typedef Documentation

◆ keepalive_object_t

typedef struct keepalive_object_t keepalive_object_t

Base object used for locking and reference counting

NOTE: Pointers to keepalive_object_t are assumed to be also pointers to containing object i.e. keepalive_object_t must be the 1st member in containing object structure.

Basic assumptions:

  • functions that end with "_locked" assume that object has already been validated and locked
  • functions that do not end with "_locked" will lock the object before touching internals and unlock again before returning
  • callbacks need to be called in unlocked state to avoid deadlocks

Notable exceptions:

  • initial stages of object initialization and final states of object destruction happen in context where locking is not applicable

Rough object life cycle:

  1. keepalive_object_ctor()
  • object is counted as having one external reference
  • all features available for use
  1. keepalive_object_ref_internal_locked()
  • object will not be deleted until all internal refs are dropped
  • timers / dbus calls etc must hold an internal ref until finalized
  1. last keepalive_object_unref_external_locked()
  • keepalive_object_shutdown_locked() shedules shutdown
  • attempting to add external refs aborts
  1. keepalive_object_shutdown_cb()
  • shutdown notification is made
  • existing timers are either canceled / waited to complete
  • new timers can't be added
  1. last keepalive_object_unref_internal_locked()
  • attempt to add/remove refs will abort
  1. keepalive_object_unlock()
  • no more references triggers delete
  1. keepalive_object_destroy()
  • destroy notification is made
  1. keepalive_object_dtor() -> further lock/unlock attempts will abort
  2. dynamic memory is released

Function Documentation

◆ keepalive_object_ctor()

void keepalive_object_ctor ( keepalive_object_t * self,
const char * identity,
GDestroyNotify shutdown_locked_cb,
GDestroyNotify delete_cb )

Object constructor

Parameters
selfObject pointer
identityHuman readable type identification string
shutdown_locked_cbShutdown notification callback function
delete_cbDestroy notification callback function

◆ keepalive_object_dtor()

void keepalive_object_dtor ( keepalive_object_t * self)

Object destructor

Parameters
selfObject pointer

◆ keepalive_object_lock()

void keepalive_object_lock ( keepalive_object_t * self)

Lock object

Attempt to lock already locked object is a logic fault and must be expected to cause a deadlock.

Attempt to lock invalid object is logic fault and must be expected to cause crash or abort.

Parameters
selfObject pointer

◆ keepalive_object_unlock()

void keepalive_object_unlock ( keepalive_object_t * self)

Unlock object

Attempt to unlock invalid or already unlocked object is a logic fault and must expected to crash or abort.

Parameters
selfObject pointer

◆ keepalive_object_ref_external_locked()

void * keepalive_object_ref_external_locked ( keepalive_object_t * self)

Add external reference to object

Implies strong reference, which blocks both object shutdown and destroy.

Attempt to add external references after external reference count has already dropped to zero is a logic fault and will cause an abort.

Parameters
selfObject pointer
Returns
object pointer

◆ keepalive_object_ref_internal_locked()

void * keepalive_object_ref_internal_locked ( keepalive_object_t * self)

Add interal reference to object

Implies weak reference, which blocks object destruction, but not logical shutdown.

Attempt to add internal references after external and external reference counts have already dropped to zero is a logic fault and will cause an abort.

Parameters
selfObject pointer
Returns
object pointer

◆ keepalive_object_unref_external_locked()

void keepalive_object_unref_external_locked ( keepalive_object_t * self)

Remove external reference to object

Attempt to remove external reference when external reference count is already zero causes an abort.

Parameters
selfObject pointer

◆ keepalive_object_unref_internal_locked()

void keepalive_object_unref_internal_locked ( keepalive_object_t * self)

Remove internal reference to object

Attempt to remove internal reference when internal reference count is already zero causes an abort.

Parameters
selfObject pointer

◆ keepalive_object_unref_internal_cb()

void keepalive_object_unref_internal_cb ( void * aptr)

Callback function for removing internal reference to object

Meant to be used as destroy notification for glib timeouts, dbus pending calls, etc.

Locks object, decrements internal reference count and unlocks the object again.

Parameters
selfObject pointer

◆ keepalive_object_timer_start_locked()

void keepalive_object_timer_start_locked ( keepalive_object_t * self,
guint * timer_id,
guint interval,
GSourceFunc notify_cb )

Add timer

Add glib timer, bind it to object in such manner that object is not deleted until the timer is either cancelled or finalized.

If timer_id already contains non-zero value, it is canceled 1st.

Parameters
selfObject pointer
timer_idWhere timer id is stored
intervalTimer delay in ms; use zero for idle callback
notify_cbTimer trigger callback

◆ keepalive_object_timer_stop_locked()

void keepalive_object_timer_stop_locked ( keepalive_object_t * self,
guint * timer_id )

Remove timer

Cancel glib timer and unbind it from object.

Parameters
selfObject pointer
timer_idWhere timer id is stored

◆ keepalive_object_in_shutdown_locked()

bool keepalive_object_in_shutdown_locked ( keepalive_object_t * self)

Predicate for: object is being shut down

Parameters
selfObject pointer
Returns
true if object is waiting to be deleted, false otherwise

◆ keepalive_object_ipc_start_locked_va()

void keepalive_object_ipc_start_locked_va ( keepalive_object_t * self,
DBusPendingCall ** where,
DBusPendingCallNotifyFunction notify_cb,
DBusConnection * connection,
const char * service,
const char * object,
const char * interface,
const char * method,
int arg_type,
va_list va )

Start D-Bus method call

Construct D-Bus method call message. Send it using the specified connection. Bind reply handler to object in such manner that object is not deleted until the pending call is either cancelled or finalized.

If where already contains non-zero value, it is canceled 1st.

Parameters
selfObject pointer
whereWhere pending call ref is stored
notify_cbNotify callback for finished call
connectionD-Bus connection to use
serviceD-Bus service name
objectD-Bus object path
interfaceD-Bus interface name
methodD-Bus method name
arg_typeThe 1st argument type
vaFurther arguments as va-list

◆ keepalive_object_ipc_cancel_locked()

void keepalive_object_ipc_cancel_locked ( keepalive_object_t * self,
DBusPendingCall ** where )

Cancel D-Bus method call

Cancel D-Bus pending call and unbind it from object.

Parameters
selfObject pointer
whereWhere pending call ref is stored

◆ keepalive_object_ipc_finish_locked()

bool keepalive_object_ipc_finish_locked ( keepalive_object_t * self,
DBusPendingCall ** where,
DBusPendingCall * what )

Finish D-Bus method call

Unbind D-Bus pending call from object.

Parameters
selfObject pointer
whereWhere pending call ref is stored
whatPending call we are expecting reply to
Returns
true if stored pending call matched expected and was unbound from object, false otherwise

◆ keepalive_object_iowatch_start_locked()

void keepalive_object_iowatch_start_locked ( keepalive_object_t * self,
guint * iowatch_id,
int fd,
GIOCondition cnd,
GIOFunc io_cb )

Add iowatch

Add glib io watch, bind it to object in such manner that object is not deleted until the io watch is removed.

If watch_id already contains non-zero value, it is canceled 1st.

Parameters
selfObject pointer
watch_idWhere io watch id is stored
fdFile descriptor to watch
cndConditions that trigger notification
io_cbNotification callback

◆ keepalive_object_iowatch_stop_locked()

void keepalive_object_iowatch_stop_locked ( keepalive_object_t * self,
guint * iowatch_id )

Remove iowatch

Cancel glib io watch and unbind it from object.

Parameters
selfObject pointer
watch_idWhere io watch id is stored