Sfoglia il codice sorgente

base: BPending: transform BPending into BSmallPending, which doesn't keep a pointer to its BPendingGroup, and implement
BPending on top of BSmallPending

ambrop7 13 anni fa
parent
commit
d547f87417

+ 39 - 14
base/BPending.c

@@ -69,7 +69,7 @@ void BPendingGroup_ExecuteJob (BPendingGroup *g)
     DebugObject_Access(&g->d_obj);
     
     // get a job
-    BPending *p = BPending__List_First(&g->jobs);
+    BSmallPending *p = BPending__List_First(&g->jobs);
     ASSERT(p->pending_node.next != p)
     ASSERT(p->pending)
     
@@ -87,17 +87,16 @@ void BPendingGroup_ExecuteJob (BPendingGroup *g)
     return;
 }
 
-BPending * BPendingGroup_PeekJob (BPendingGroup *g)
+BSmallPending * BPendingGroup_PeekJob (BPendingGroup *g)
 {
     DebugObject_Access(&g->d_obj);
     
     return BPending__List_First(&g->jobs);
 }
 
-void BPending_Init (BPending *o, BPendingGroup *g, BPending_handler handler, void *user)
+void BSmallPending_Init (BSmallPending *o, BPendingGroup *g, BSmallPending_handler handler, void *user)
 {
     // init arguments
-    o->g = g;
     o->handler = handler;
     o->user = user;
     
@@ -108,36 +107,36 @@ void BPending_Init (BPending *o, BPendingGroup *g, BPending_handler handler, voi
 #endif
     
     // increment pending counter
-    DebugCounter_Increment(&o->g->pending_ctr);
+    DebugCounter_Increment(&g->pending_ctr);
     
     // init debug object
     DebugObject_Init(&o->d_obj);
 }
 
-void BPending_Free (BPending *o)
+void BSmallPending_Free (BSmallPending *o, BPendingGroup *g)
 {
-    DebugCounter_Decrement(&o->g->pending_ctr);
+    DebugCounter_Decrement(&g->pending_ctr);
     DebugObject_Free(&o->d_obj);
     ASSERT(o->pending == (o->pending_node.next != o))
     
     // remove from jobs list
     if (o->pending_node.next != o) {
-        BPending__List_Remove(&o->g->jobs, o);
+        BPending__List_Remove(&g->jobs, o);
     }
 }
 
-void BPending_Set (BPending *o)
+void BSmallPending_Set (BSmallPending *o, BPendingGroup *g)
 {
     DebugObject_Access(&o->d_obj);
     ASSERT(o->pending == (o->pending_node.next != o))
     
     // remove from jobs list
     if (o->pending_node.next != o) {
-        BPending__List_Remove(&o->g->jobs, o);
+        BPending__List_Remove(&g->jobs, o);
     }
     
     // insert to jobs list
-    BPending__List_Prepend(&o->g->jobs, o);
+    BPending__List_Prepend(&g->jobs, o);
     
     // set pending
 #ifndef NDEBUG
@@ -145,14 +144,14 @@ void BPending_Set (BPending *o)
 #endif
 }
 
-void BPending_Unset (BPending *o)
+void BSmallPending_Unset (BSmallPending *o, BPendingGroup *g)
 {
     DebugObject_Access(&o->d_obj);
     ASSERT(o->pending == (o->pending_node.next != o))
     
     if (o->pending_node.next != o) {
         // remove from jobs list
-        BPending__List_Remove(&o->g->jobs, o);
+        BPending__List_Remove(&g->jobs, o);
         
         // set not pending
         o->pending_node.next = o;
@@ -162,10 +161,36 @@ void BPending_Unset (BPending *o)
     }
 }
 
-int BPending_IsSet (BPending *o)
+int BSmallPending_IsSet (BSmallPending *o)
 {
     DebugObject_Access(&o->d_obj);
     ASSERT(o->pending == (o->pending_node.next != o))
     
     return (o->pending_node.next != o);
 }
+
+void BPending_Init (BPending *o, BPendingGroup *g, BPending_handler handler, void *user)
+{
+    BSmallPending_Init(&o->base, g, handler, user);
+    o->g = g;
+}
+
+void BPending_Free (BPending *o)
+{
+    BSmallPending_Free(&o->base, o->g);
+}
+
+void BPending_Set (BPending *o)
+{
+    BSmallPending_Set(&o->base, o->g);
+}
+
+void BPending_Unset (BPending *o)
+{
+    BSmallPending_Unset(&o->base, o->g);
+}
+
+int BPending_IsSet (BPending *o)
+{
+    return BSmallPending_IsSet(&o->base);
+}

+ 76 - 5
base/BPending.h

@@ -40,11 +40,22 @@
 #include <structure/SLinkedList.h>
 #include <base/DebugObject.h>
 
-struct BPending_s;
+struct BSmallPending_s;
 
 #include "BPending_list.h"
 #include <structure/SLinkedList_decl.h>
 
+/**
+ * Job execution handler.
+ * It is guaranteed that the associated {@link BSmallPending} object was
+ * in set state.
+ * The {@link BSmallPending} object enters not set state before the handler
+ * is called.
+ * 
+ * @param user as in {@link BSmallPending_Init}
+ */
+typedef void (*BSmallPending_handler) (void *user);
+
 /**
  * Job execution handler.
  * It is guaranteed that the associated {@link BPending} object was
@@ -68,8 +79,7 @@ typedef struct {
 /**
  * Object for queuing a job for execution.
  */
-typedef struct BPending_s {
-    BPendingGroup *g;
+typedef struct BSmallPending_s {
     BPending_handler handler;
     void *user;
     BPending__ListNode pending_node; // optimization: if not pending, .next is this
@@ -77,6 +87,16 @@ typedef struct BPending_s {
     uint8_t pending;
 #endif
     DebugObject d_obj;
+} BSmallPending;
+
+/**
+ * Object for queuing a job for execution. This is a convenience wrapper
+ * around {@link BSmallPending} with an extra field to remember the
+ * {@link BPendingGroup} being used.
+ */
+typedef struct {
+    BSmallPending base;
+    BPendingGroup *g;
 } BPending;
 
 /**
@@ -88,7 +108,8 @@ void BPendingGroup_Init (BPendingGroup *g);
 
 /**
  * Frees the object.
- * There must be no {@link BPending} objects using this group.
+ * There must be no {@link BPending} or {@link BSmallPending} objects using
+ * this group.
  * 
  * @param g the object
  */
@@ -118,7 +139,57 @@ void BPendingGroup_ExecuteJob (BPendingGroup *g);
  * @param g the object
  * @return the top job if there is at least one job, NULL if not
  */
-BPending * BPendingGroup_PeekJob (BPendingGroup *g);
+BSmallPending * BPendingGroup_PeekJob (BPendingGroup *g);
+
+/**
+ * Initializes the object.
+ * The object is initialized in not set state.
+ * 
+ * @param o the object
+ * @param g pending group to use
+ * @param handler job execution handler
+ * @param user value to pass to handler
+ */
+void BSmallPending_Init (BSmallPending *o, BPendingGroup *g, BSmallPending_handler handler, void *user);
+
+/**
+ * Frees the object.
+ * The execution handler will not be called after the object
+ * is freed.
+ * 
+ * @param o the object
+ * @param g pending group. Must be the same as was used in {@link BSmallPending_Init}.
+ */
+void BSmallPending_Free (BSmallPending *o, BPendingGroup *g);
+
+/**
+ * Enables the job, pushing it to the top of the job list.
+ * If the object was already in set state, the job is removed from its
+ * current position in the list before being pushed.
+ * The object enters set state.
+ * 
+ * @param o the object
+ * @param g pending group. Must be the same as was used in {@link BSmallPending_Init}.
+ */
+void BSmallPending_Set (BSmallPending *o, BPendingGroup *g);
+
+/**
+ * Disables the job, removing it from the job list.
+ * If the object was not in set state, nothing is done.
+ * The object enters not set state.
+ * 
+ * @param o the object
+ * @param g pending group. Must be the same as was used in {@link BSmallPending_Init}.
+ */
+void BSmallPending_Unset (BSmallPending *o, BPendingGroup *g);
+
+/**
+ * Checks if the job is in set state.
+ * 
+ * @param o the object
+ * @return 1 if in set state, 0 if not
+ */
+int BSmallPending_IsSet (BSmallPending *o);
 
 /**
  * Initializes the object.

+ 1 - 1
base/BPending_list.h

@@ -1,4 +1,4 @@
 #define SLINKEDLIST_PARAM_NAME BPending__List
 #define SLINKEDLIST_PARAM_FEATURE_LAST 0
-#define SLINKEDLIST_PARAM_TYPE_ENTRY struct BPending_s
+#define SLINKEDLIST_PARAM_TYPE_ENTRY struct BSmallPending_s
 #define SLINKEDLIST_PARAM_MEMBER_NODE pending_node

+ 1 - 1
system/BReactor_badvpn.c

@@ -1039,7 +1039,7 @@ BPendingGroup * BReactor_PendingGroup (BReactor *bsys)
     return &bsys->pending_jobs;
 }
 
-int BReactor_Synchronize (BReactor *bsys, BPending *ref)
+int BReactor_Synchronize (BReactor *bsys, BSmallPending *ref)
 {
     ASSERT(ref)
     

+ 5 - 5
system/BReactor_badvpn.h

@@ -292,8 +292,8 @@ int BReactor_Init (BReactor *bsys) WARN_UNUSED;
 /**
  * Frees the reactor.
  * Must not be called from within the event loop ({@link BReactor_Exec}).
- * There must be no {@link BPending} objects using the pending group
- * returned by {@link BReactor_PendingGroup}.
+ * There must be no {@link BPending} or {@link BSmallPending} objects using the
+ * pending group returned by {@link BReactor_PendingGroup}.
  * There must be no running timers in this reactor.
  * There must be no limit objects in this reactor.
  * There must be no file descriptors or handles registered
@@ -398,8 +398,8 @@ void BReactor_RemoveTimer (BReactor *bsys, BTimer *bt);
  * (timers, file descriptors and Windows handles).
  * The returned pending group may only be used as an argument to {@link BPending_Init},
  * and must not be accessed by other means.
- * All {@link BPending} objects using this group must be freed before freeing
- * the reactor.
+ * All {@link BPending} and {@link BSmallPending} objects using this group must be
+ * freed before freeing the reactor.
  * 
  * @param bsys the object
  * @return pending group for scheduling jobs for the reactor to execute
@@ -424,7 +424,7 @@ BPendingGroup * BReactor_PendingGroup (BReactor *bsys);
  * @return 1 if the reference job was reached,
  *         0 if {@link BReactor_Quit} was called (either while executing a job, or before)
  */
-int BReactor_Synchronize (BReactor *bsys, BPending *ref);
+int BReactor_Synchronize (BReactor *bsys, BSmallPending *ref);
 
 #ifndef BADVPN_USE_WINAPI
 

+ 1 - 1
system/BReactor_glib.c

@@ -298,7 +298,7 @@ BPendingGroup * BReactor_PendingGroup (BReactor *bsys)
     return &bsys->pending_jobs;
 }
 
-int BReactor_Synchronize (BReactor *bsys, BPending *ref)
+int BReactor_Synchronize (BReactor *bsys, BSmallPending *ref)
 {
     DebugObject_Access(&bsys->d_obj);
     ASSERT(ref)

+ 1 - 1
system/BReactor_glib.h

@@ -102,7 +102,7 @@ void BReactor_SetTimerAfter (BReactor *bsys, BTimer *bt, btime_t after);
 void BReactor_SetTimerAbsolute (BReactor *bsys, BTimer *bt, btime_t time);
 void BReactor_RemoveTimer (BReactor *bsys, BTimer *bt);
 BPendingGroup * BReactor_PendingGroup (BReactor *bsys);
-int BReactor_Synchronize (BReactor *bsys, BPending *ref);
+int BReactor_Synchronize (BReactor *bsys, BSmallPending *ref);
 int BReactor_AddFileDescriptor (BReactor *bsys, BFileDescriptor *bs) WARN_UNUSED;
 void BReactor_RemoveFileDescriptor (BReactor *bsys, BFileDescriptor *bs);
 void BReactor_SetFileDescriptorEvents (BReactor *bsys, BFileDescriptor *bs, int events);

+ 1 - 1
tun2socks/tun2socks.c

@@ -80,7 +80,7 @@
     BPending_Free(&sync_mark);
 
 #define SYNC_COMMIT \
-    BReactor_Synchronize(&ss, &sync_mark); \
+    BReactor_Synchronize(&ss, &sync_mark.base); \
     BPending_Free(&sync_mark);
 
 // command-line options