]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add preparation for callbacks based on ident
authorAlan T. DeKok <aland@freeradius.org>
Wed, 18 Jan 2017 17:03:06 +0000 (12:03 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Wed, 18 Jan 2017 17:03:06 +0000 (12:03 -0500)
src/util/control.c
src/util/control.h

index 2e088629b5f9e56423dba4cc5a9ebe2e26f2d9e4..e131a34100dcd3104d53401bdc27642d1d86d4e1 100644 (file)
@@ -53,6 +53,7 @@ typedef enum fr_control_message_status_t {
        FR_CONTROL_MESSAGE_DONE                         //!< the message is done (set only by receiver)
 } fr_control_message_status_t;
 
+
 /**
  *  The header for the control message
  */
@@ -62,6 +63,15 @@ typedef struct fr_control_message_t {
        size_t                          data_size;      //!< size of the data we're sending
 } fr_control_message_t;
 
+
+typedef struct fr_control_ctx_t {
+       uint32_t                        id;             //!< id of this callback
+       void                            *ctx;           //!< context for the callback
+       fr_control_callback_t           callback;       //!< the function to call
+} fr_control_ctx_t;
+
+#define MAX_IDENT (32)
+
 /**
  *  The control structure.
  */
@@ -71,6 +81,8 @@ struct fr_control_t {
        fr_atomic_queue_t       *aq;                    //!< destination AQ
 
        fr_ring_buffer_t        *rb;                    //!< a ring buffer containing my messages to send.
+
+       fr_control_ctx_t        ident[MAX_IDENT];       //!< callbacks
 };
 
 
@@ -365,3 +377,64 @@ int fr_control_message_service_kevent(UNUSED fr_atomic_queue_t *aq, struct keven
 
        return 1;
 }
+
+
+/** Register a callback for an ID
+ *
+ * @param[in] c the control structure
+ * @param[in] id the ident of this message.
+ * @param[in] ctx the context for the callback
+ * @param[in] callback the callback function
+ * @return
+ *     - <0 on error
+ *     - 0 on success
+ */
+int fr_control_callback_add(fr_control_t *c, uint32_t id, void *ctx, fr_control_callback_t callback)
+{
+#ifndef NDEBUG
+       (void) talloc_get_type_abort(c, fr_control_t);
+#endif
+
+       if (id >= MAX_IDENT) return -1;
+
+       /*
+        *      Re-registering the same thing is OK.
+        */
+       if ((c->ident[id].ctx == ctx) &&
+           (c->ident[id].callback == callback)) {
+               return 0;
+       }
+
+       if (c->ident[id].callback != NULL) return -1;
+
+       c->ident[id].id = id;
+       c->ident[id].ctx = ctx;
+       c->ident[id].callback = callback;
+
+       return 0;
+}
+
+/** Delete a callback for an ID
+ *
+ * @param[in] c the control structure
+ * @param[in] id the ident of this message.
+ * @return
+ *     - <0 on error
+ *     - 0 on success
+ */
+int fr_control_callback_delete(fr_control_t *c, uint32_t id)
+{
+#ifndef NDEBUG
+       (void) talloc_get_type_abort(c, fr_control_t);
+#endif
+
+       if (id >= MAX_IDENT) return -1;
+
+       if (c->ident[id].callback == NULL) return 0;
+
+       c->ident[id].id = 0;
+       c->ident[id].ctx = NULL;
+       c->ident[id].callback = NULL;
+
+       return 0;
+}
index 26485f3a7e44afbbc0dfa21ecf1a562070c2a464..942a3dca89d9cf4dfafd68079fd7b12a7d44c6c8 100644 (file)
@@ -26,6 +26,7 @@
 RCSIDH(control_h, "$Id$")
 
 #include <freeradius-devel/util/atomic_queue.h>
+#include <freeradius-devel/util/time.h>
 
 #include <sys/types.h>
 #include <sys/event.h>
@@ -40,6 +41,7 @@ extern "C" {
  *  Multiple-producer, single consumer.
  */
 typedef struct fr_control_t fr_control_t;
+typedef        void (*fr_control_callback_t)(void *ctx, void const *data, size_t data_size, fr_time_t now);
 
 /*
  *     A list of pre-allocated IDs, so that the callers don't have to manage their own.
@@ -57,6 +59,8 @@ int fr_control_message_service_kevent(fr_atomic_queue_t *aq, struct kevent const
 int fr_control_message_push(fr_control_t *c, uint32_t id, void *data, size_t data_size) CC_HINT(nonnull);
 ssize_t fr_control_message_pop(fr_atomic_queue_t *aq, uint32_t *p_id, void *data, size_t data_size) CC_HINT(nonnull);
 
+int fr_control_callback_add(fr_control_t *c, uint32_t id, void *ctx, fr_control_callback_t callback) CC_HINT(nonnull(1,4));
+int fr_control_callback_delete(fr_control_t *c, uint32_t id) CC_HINT(nonnull);
 
 #ifdef __cplusplus
 }