Przeglądaj źródła

system: BReactor: transform BTimer into BSmallTimer which doesn't have a default time, and implement BTimer on top of
BSmallTimer

ambrop7 13 lat temu
rodzic
commit
70e6c3ddd3

+ 49 - 22
system/BReactor_badvpn.c

@@ -59,7 +59,7 @@
 #define BTIMER_MIN_RUNNING_TIME (BTIME_MIN + 2)
 #define BTIMER_IS_RUNNING_TIME(x) ((x) >= BTIMER_MIN_RUNNING_TIME)
 
-static int compare_timers (BTimer *t1, BTimer *t2)
+static int compare_timers (BSmallTimer *t1, BSmallTimer *t2)
 {
     int cmp = B_COMPARE(t1->absTime, t2->absTime);
     if (cmp) {
@@ -77,7 +77,7 @@ static int move_expired_timers (BReactor *bsys, btime_t now)
     int moved = 0;
     
     // move timed out timers to the expired list
-    BTimer *timer;
+    BSmallTimer *timer;
     while (timer = BReactor__TimersTree_GetFirst(&bsys->timers_tree, 0)) {
         ASSERT(BTIMER_IS_RUNNING_TIME(timer->absTime))
         
@@ -103,7 +103,7 @@ static int move_expired_timers (BReactor *bsys, btime_t now)
 static void move_first_timers (BReactor *bsys)
 {
     // get the time of the first timer
-    BTimer *first_timer = BReactor__TimersTree_GetFirst(&bsys->timers_tree, 0);
+    BSmallTimer *first_timer = BReactor__TimersTree_GetFirst(&bsys->timers_tree, 0);
     ASSERT(first_timer)
     ASSERT(BTIMER_IS_RUNNING_TIME(first_timer->absTime))
     btime_t first_time = first_timer->absTime;
@@ -118,7 +118,7 @@ static void move_first_timers (BReactor *bsys)
     first_timer->absTime = BTIMER_EXPIRED_TIME;
     
     // also move other timers with the same timeout
-    BTimer *timer;
+    BSmallTimer *timer;
     while (timer = BReactor__TimersTree_GetFirst(&bsys->timers_tree, 0)) {
         ASSERT(BTIMER_IS_RUNNING_TIME(timer->absTime))
         ASSERT(timer->absTime >= first_time)
@@ -303,7 +303,7 @@ static void wait_for_events (BReactor *bsys)
     btime_t now = 0; // to remove warning
     
     // compute timeout
-    BTimer *first_timer = BReactor__TimersTree_GetFirst(&bsys->timers_tree, 0);
+    BSmallTimer *first_timer = BReactor__TimersTree_GetFirst(&bsys->timers_tree, 0);
     if (first_timer) {
         ASSERT(BTIMER_IS_RUNNING_TIME(first_timer->absTime))
         
@@ -552,19 +552,29 @@ void BFileDescriptor_Init (BFileDescriptor *bs, int fd, BFileDescriptor_handler
 
 #endif
 
-void BTimer_Init (BTimer *bt, btime_t msTime, BTimer_handler handler, void *handler_pointer)
+void BSmallTimer_Init (BSmallTimer *bt, BSmallTimer_handler handler, void *handler_pointer)
 {
-    bt->msTime = msTime;
     bt->handler = handler;
     bt->handler_pointer = handler_pointer;
     bt->absTime = BTIMER_INACTIVE_TIME;
 }
 
-int BTimer_IsRunning (BTimer *bt)
+int BSmallTimer_IsRunning (BSmallTimer *bt)
 {
     return (bt->absTime != BTIMER_INACTIVE_TIME);
 }
 
+void BTimer_Init (BTimer *bt, btime_t msTime, BTimer_handler handler, void *user)
+{
+    BSmallTimer_Init(&bt->base, handler, user);
+    bt->msTime = msTime;
+}
+
+int BTimer_IsRunning (BTimer *bt)
+{
+    return BSmallTimer_IsRunning(&bt->base);
+}
+
 int BReactor_Init (BReactor *bsys)
 {
     BLog(BLOG_DEBUG, "Reactor initializing");
@@ -754,7 +764,7 @@ int BReactor_Exec (BReactor *bsys)
         // dispatch timer
         LinkedList1Node *list_node = LinkedList1_GetFirst(&bsys->timers_expired_list);
         if (list_node) {
-            BTimer *timer = UPPER_OBJECT(list_node, BTimer, list_node);
+            BSmallTimer *timer = UPPER_OBJECT(list_node, BSmallTimer, list_node);
             ASSERT(timer->absTime == BTIMER_EXPIRED_TIME)
             
             // remove from expired list
@@ -961,20 +971,17 @@ void BReactor_Quit (BReactor *bsys, int code)
     bsys->exit_code = code;
 }
 
-void BReactor_SetTimer (BReactor *bsys, BTimer *bt)
-{
-    BReactor_SetTimerAfter(bsys, bt, bt->msTime);
-}
-
-void BReactor_SetTimerAfter (BReactor *bsys, BTimer *bt, btime_t after)
-{
-    BReactor_SetTimerAbsolute(bsys, bt, btime_add(btime_gettime(), after));
-}
-
-void BReactor_SetTimerAbsolute (BReactor *bsys, BTimer *bt, btime_t time)
+void BReactor_SetSmallTimer (BReactor *bsys, BSmallTimer *bt, int mode, btime_t time)
 {
+    ASSERT(mode == BTIMER_SET_ABSOLUTE || mode == BTIMER_SET_RELATIVE)
+    
     // unlink it if it's already in the list
-    BReactor_RemoveTimer(bsys, bt);
+    BReactor_RemoveSmallTimer(bsys, bt);
+    
+    // if mode is relative, add current time
+    if (mode == BTIMER_SET_RELATIVE) {
+        time = btime_add(btime_gettime(), time);
+    }
     
     // don't allow reserved times
     if (!BTIMER_IS_RUNNING_TIME(time)) {
@@ -989,7 +996,7 @@ void BReactor_SetTimerAbsolute (BReactor *bsys, BTimer *bt, btime_t time)
     ASSERT_EXECUTE(res)
 }
 
-void BReactor_RemoveTimer (BReactor *bsys, BTimer *bt)
+void BReactor_RemoveSmallTimer (BReactor *bsys, BSmallTimer *bt)
 {
     if (bt->absTime == BTIMER_INACTIVE_TIME) {
         return;
@@ -1007,6 +1014,26 @@ void BReactor_RemoveTimer (BReactor *bsys, BTimer *bt)
     bt->absTime = BTIMER_INACTIVE_TIME;
 }
 
+void BReactor_SetTimer (BReactor *bsys, BTimer *bt)
+{
+    BReactor_SetSmallTimer(bsys, &bt->base, BTIMER_SET_RELATIVE, bt->msTime);
+}
+
+void BReactor_SetTimerAfter (BReactor *bsys, BTimer *bt, btime_t after)
+{
+    BReactor_SetSmallTimer(bsys, &bt->base, BTIMER_SET_RELATIVE, after);
+}
+
+void BReactor_SetTimerAbsolute (BReactor *bsys, BTimer *bt, btime_t time)
+{
+    BReactor_SetSmallTimer(bsys, &bt->base, BTIMER_SET_ABSOLUTE, time);
+}
+
+void BReactor_RemoveTimer (BReactor *bsys, BTimer *bt)
+{
+    return BReactor_RemoveSmallTimer(bsys, &bt->base);
+}
+
 BPendingGroup * BReactor_PendingGroup (BReactor *bsys)
 {
     return &bsys->pending_jobs;

+ 69 - 6
system/BReactor_badvpn.h

@@ -67,7 +67,7 @@
 #include <system/BTime.h>
 #include <base/BPending.h>
 
-struct BTimer_t;
+struct BSmallTimer_t;
 
 #include "BReactor_badvpn_timerstree.h"
 #include <structure/SAvl_decl.h>
@@ -79,22 +79,59 @@ struct BTimer_t;
  * This function is being called from within the timer's previosly
  * associated reactor.
  *
- * @param user value passed to {@link BTimer_Init}
+ * @param user value passed to {@link BSmallTimer_Init}
  */
-typedef void (*BTimer_handler) (void *user);
+typedef void (*BSmallTimer_handler) (void *user);
 
 /**
  * Timer object used with {@link BReactor}.
  */
-typedef struct BTimer_t {
-    btime_t msTime;
-    BTimer_handler handler;
+typedef struct BSmallTimer_t {
+    BSmallTimer_handler handler;
     void *handler_pointer;
     btime_t absTime;
     union {
         BReactor__TimersTreeNode tree_node;
         LinkedList1Node list_node;
     };
+} BSmallTimer;
+
+/**
+ * Initializes the timer object.
+ * The timer object is initialized in not running state.
+ *
+ * @param bt the object
+ * @param handler handler function invoked when the timer expires
+ * @param user value to pass to the handler function
+ */
+void BSmallTimer_Init (BSmallTimer *bt, BSmallTimer_handler handler, void *user);
+
+/**
+ * Checks if the timer is running.
+ *
+ * @param bt the object
+ * @return 1 if running, 0 if not running
+ */
+int BSmallTimer_IsRunning (BSmallTimer *bt);
+
+/**
+ * Handler function invoked when the timer expires.
+ * The timer was in running state.
+ * The timer enters not running state before this function is invoked.
+ * This function is being called from within the timer's previosly
+ * associated reactor.
+ *
+ * @param user value passed to {@link BTimer_Init}
+ */
+typedef void (*BTimer_handler) (void *user);
+
+/**
+ * Timer object used with {@link BReactor}. This is a legacy wrapper
+ * around {@link BSmallTimer} with an extra field for the default time.
+ */
+typedef struct {
+    BSmallTimer base;
+    btime_t msTime;
 } BTimer;
 
 /**
@@ -124,6 +161,9 @@ struct BFileDescriptor_t;
 #define BREACTOR_WRITE (1 << 1)
 #define BREACTOR_ERROR (1 << 2)
 
+#define BTIMER_SET_ABSOLUTE 1
+#define BTIMER_SET_RELATIVE 2
+
 /**
  * Handler function invoked by the reactor when one or more events are detected.
  * The events argument will contain a subset of the monitored events (BREACTOR_READ, BREACTOR_WRITE),
@@ -283,6 +323,29 @@ int BReactor_Exec (BReactor *bsys);
  */
 void BReactor_Quit (BReactor *bsys, int code);
 
+/**
+ * Starts a timer to expire at the specified time.
+ * The timer must have been initialized with {@link BSmallTimer_Init}.
+ * If the timer is in running state, it must be associated with this reactor.
+ * The timer enters running state, associated with this reactor.
+ *
+ * @param bsys the object
+ * @param bt timer to start
+ * @param mode interpretation of time (BTIMER_SET_ABSOLUTE or BTIMER_SET_RELATIVE)
+ * @param time absolute or relative expiration time
+ */
+void BReactor_SetSmallTimer (BReactor *bsys, BSmallTimer *bt, int mode, btime_t time);
+
+/**
+ * Stops a timer.
+ * If the timer is in running state, it must be associated with this reactor.
+ * The timer enters not running state.
+ *
+ * @param bsys the object
+ * @param bt timer to stop
+ */
+void BReactor_RemoveSmallTimer (BReactor *bsys, BSmallTimer *bt);
+
 /**
  * Starts a timer to expire after its default time.
  * The timer must have been initialized with {@link BTimer_Init}.

+ 1 - 1
system/BReactor_badvpn_timerstree.h

@@ -1,7 +1,7 @@
 #define SAVL_PARAM_NAME BReactor__TimersTree
 #define SAVL_PARAM_FEATURE_COUNTS 0
 #define SAVL_PARAM_FEATURE_NOKEYS 1
-#define SAVL_PARAM_TYPE_ENTRY struct BTimer_t
+#define SAVL_PARAM_TYPE_ENTRY struct BSmallTimer_t
 #define SAVL_PARAM_TYPE_ARG int
 #define SAVL_PARAM_FUN_COMPARE_ENTRIES(arg, entry1, entry2) compare_timers((entry1), (entry2))
 #define SAVL_PARAM_MEMBER_NODE tree_node