Skip to content

Commit

Permalink
Add return value for WFTaskFactory::XXXX_by_name(). (#1627)
Browse files Browse the repository at this point in the history
* Add return value for WFTaskFactory::XXXX_by_name().

* Update about-counter.md

* Update about-timer.md
  • Loading branch information
Barenboim authored Sep 24, 2024
1 parent 9420446 commit 91f679a
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 35 deletions.
5 changes: 3 additions & 2 deletions docs/about-counter.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,15 +160,16 @@ int main(void)
class WFTaskFactory
{
...
static void count_by_name(const std::string& counter_name);
static int count_by_name(const std::string& counter_name);

static void count_by_name(const std::string& counter_name, unsigned int n);
static int count_by_name(const std::string& counter_name, unsigned int n);
...
};
~~~
WFTaskFactory::count_by_name方法还可以传入一个整数n,表示这一次操作要增加的计数值,显然:
count_by_name("c1")等价于count_by_name("c1", 1)。
如果"c1"计数器不存在(未创建或已经完成),那么对"c1"的操作不产生任何效果,因此不会有匿名计数器野指针的问题。
函数的返回值表示被唤醒的计数器个数。当n大于1时,count_by_name操作可能让多个计数器达到目标值。

# 命名计数器详细行为定义

Expand Down
7 changes: 4 additions & 3 deletions docs/about-timer.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ public:
time_t seconds, long nanoseconds,
timer_callback_t callback);

static void cancel_by_name(const std::string& timer_name)
static int cancel_by_name(const std::string& timer_name)
{
cancel_by_name(const std::string& timer_name, (size_t)-1);
}

static void cancel_by_name(const std::string& timer_name, size_t max);
static int cancel_by_name(const std::string& timer_name, size_t max);
};
~~~
我们通过seconds和nanoseconds两个参数来指定一个定时器的定时时间。其中,nanoseconds的取值范围在[0,1000000000)。
Expand All @@ -35,7 +35,8 @@ public:
如果在创建定时器任务时传入一个名称,那么这个定时器就可以在被提前中断。
中断一个定时任务的方法是通过WFTaskFactory::cancel_by_name这个接口,这个接口默认情况下,会取消这个名称下的所有定时器。
因此,我们也支持传入一个max参数,让操作最多取消max个定时器。当然,如果没有这个名称下的定时器,cancel操作不会产生任何效果。
因此,我们也支持传入一个max参数,让操作最多取消max个定时器。无论哪个接口,返回值都是代表实际被取消的定时器个数。
如果没有这个名称下的定时器,cancel操作不会产生任何效果,并返回0。
定时器在被创建之后就可取消,并非一定要等它被启动之后。以这个代码为例:
~~~cpp
#include <stdio.h>
Expand Down
47 changes: 31 additions & 16 deletions src/factory/WFTaskFactory.cc
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ static class __NamedTimerMap
timer_callback_t&& cb);

public:
void cancel(const std::string& name, size_t max);
int cancel(const std::string& name, size_t max);

private:
struct rb_root root_;
Expand Down Expand Up @@ -272,10 +272,11 @@ WFTimerTask *__NamedTimerMap::create(const std::string& name,
return task;
}

void __NamedTimerMap::cancel(const std::string& name, size_t max)
int __NamedTimerMap::cancel(const std::string& name, size_t max)
{
struct __timer_node *node;
TimerList *timers;
int ret = 0;

mutex_.lock();
timers = __get_object_list<TimerList>(name, &root_, false);
Expand All @@ -296,6 +297,7 @@ void __NamedTimerMap::cancel(const std::string& name, size_t max)

node->task = NULL;
max--;
ret++;
if (timers->empty())
{
rb_erase(&timers->rb, &root_);
Expand All @@ -306,6 +308,7 @@ void __NamedTimerMap::cancel(const std::string& name, size_t max)

mutex_.unlock();
delete timers;
return ret;
}

WFTimerTask *WFTaskFactory::create_timer_task(const std::string& name,
Expand All @@ -317,9 +320,9 @@ WFTimerTask *WFTaskFactory::create_timer_task(const std::string& name,
std::move(callback));
}

void WFTaskFactory::cancel_by_name(const std::string& name, size_t max)
int WFTaskFactory::cancel_by_name(const std::string& name, size_t max)
{
__timer_map.cancel(name, max);
return __timer_map.cancel(name, max);
}

/****************** Named Counter ******************/
Expand All @@ -342,7 +345,7 @@ static class __NamedCounterMap
WFCounterTask *create(const std::string& name, unsigned int target_value,
counter_callback_t&& cb);

void count_n(const std::string& name, unsigned int n);
int count_n(const std::string& name, unsigned int n);
void count(CounterList *counters, struct __counter_node *node);

void remove(CounterList *counters, struct __counter_node *node)
Expand Down Expand Up @@ -444,12 +447,13 @@ bool __NamedCounterMap::count_n_locked(CounterList *counters, unsigned int n,
return false;
}

void __NamedCounterMap::count_n(const std::string& name, unsigned int n)
int __NamedCounterMap::count_n(const std::string& name, unsigned int n)
{
LIST_HEAD(task_list);
struct __counter_node *node;
CounterList *counters;
bool erased = false;
int ret = 0;

mutex_.lock();
counters = __get_object_list<CounterList>(name, &root_, false);
Expand All @@ -465,7 +469,10 @@ void __NamedCounterMap::count_n(const std::string& name, unsigned int n)
node = list_entry(task_list.next, struct __counter_node, list);
list_del(&node->list);
node->task->WFCounterTask::count();
ret++;
}

return ret;
}

void __NamedCounterMap::count(CounterList *counters,
Expand Down Expand Up @@ -496,9 +503,9 @@ WFCounterTask *WFTaskFactory::create_counter_task(const std::string& name,
return __counter_map.create(name, target_value, std::move(callback));
}

void WFTaskFactory::count_by_name(const std::string& name, unsigned int n)
int WFTaskFactory::count_by_name(const std::string& name, unsigned int n)
{
__counter_map.count_n(name, n);
return __counter_map.count_n(name, n);
}

/****************** Named Mailbox ******************/
Expand All @@ -521,7 +528,7 @@ static class __NamedMailboxMap
mailbox_callback_t&& cb);
WFMailboxTask *create(const std::string& name, mailbox_callback_t&& cb);

void send(const std::string& name, void *msg, size_t max);
int send(const std::string& name, void *msg, size_t max);
void send(MailboxList *mailboxes, struct __mailbox_node *node, void *msg);

void remove(MailboxList *mailboxes, struct __mailbox_node *node)
Expand Down Expand Up @@ -628,12 +635,13 @@ bool __NamedMailboxMap::send_max_locked(MailboxList *mailboxes,
return true;
}

void __NamedMailboxMap::send(const std::string& name, void *msg, size_t max)
int __NamedMailboxMap::send(const std::string& name, void *msg, size_t max)
{
LIST_HEAD(task_list);
struct __mailbox_node *node;
MailboxList *mailboxes;
bool erased = false;
int ret = 0;

mutex_.lock();
mailboxes = __get_object_list<MailboxList>(name, &root_, false);
Expand All @@ -649,7 +657,10 @@ void __NamedMailboxMap::send(const std::string& name, void *msg, size_t max)
node = list_entry(task_list.next, struct __mailbox_node, list);
list_del(&node->list);
node->task->WFMailboxTask::send(msg);
ret++;
}

return ret;
}

void __NamedMailboxMap::send(MailboxList *mailboxes,
Expand Down Expand Up @@ -680,9 +691,9 @@ WFMailboxTask *WFTaskFactory::create_mailbox_task(const std::string& name,
return __mailbox_map.create(name, std::move(callback));
}

void WFTaskFactory::send_by_name(const std::string& name, void *msg, size_t max)
int WFTaskFactory::send_by_name(const std::string& name, void *msg, size_t max)
{
__mailbox_map.send(name, msg, max);
return __mailbox_map.send(name, msg, max);
}

/****************** Named Conditional ******************/
Expand All @@ -705,7 +716,7 @@ static class __NamedConditionalMap
void **msgbuf);
WFConditional *create(const std::string& name, SubTask *task);

void signal(const std::string& name, void *msg, size_t max);
int signal(const std::string& name, void *msg, size_t max);
void signal(ConditionalList *conds, struct __conditional_node *node,
void *msg);

Expand Down Expand Up @@ -812,12 +823,13 @@ bool __NamedConditionalMap::signal_max_locked(ConditionalList *conds,
return true;
}

void __NamedConditionalMap::signal(const std::string& name, void *msg, size_t max)
int __NamedConditionalMap::signal(const std::string& name, void *msg, size_t max)
{
LIST_HEAD(cond_list);
struct __conditional_node *node;
ConditionalList *conds;
bool erased = false;
int ret = 0;

mutex_.lock();
conds = __get_object_list<ConditionalList>(name, &root_, false);
Expand All @@ -833,7 +845,10 @@ void __NamedConditionalMap::signal(const std::string& name, void *msg, size_t ma
node = list_entry(cond_list.next, struct __conditional_node, list);
list_del(&node->list);
node->cond->WFConditional::signal(msg);
ret++;
}

return ret;
}

void __NamedConditionalMap::signal(ConditionalList *conds,
Expand Down Expand Up @@ -863,10 +878,10 @@ WFConditional *WFTaskFactory::create_conditional(const std::string& name,
return __conditional_map.create(name, task);
}

void WFTaskFactory::signal_by_name(const std::string& name, void *msg,
int WFTaskFactory::signal_by_name(const std::string& name, void *msg,
size_t max)
{
__conditional_map.signal(name, msg, max);
return __conditional_map.signal(name, msg, max);
}

/****************** Named Guard ******************/
Expand Down
28 changes: 14 additions & 14 deletions src/factory/WFTaskFactory.h
Original file line number Diff line number Diff line change
Expand Up @@ -228,13 +228,13 @@ class WFTaskFactory
timer_callback_t callback);

/* cancel all timers under the name. */
static void cancel_by_name(const std::string& timer_name)
static int cancel_by_name(const std::string& timer_name)
{
WFTaskFactory::cancel_by_name(timer_name, (size_t)-1);
return WFTaskFactory::cancel_by_name(timer_name, (size_t)-1);
}

/* cancel at most 'max' timers under the name. */
static void cancel_by_name(const std::string& timer_name, size_t max);
static int cancel_by_name(const std::string& timer_name, size_t max);

/* timer in microseconds (deprecated) */
static WFTimerTask *create_timer_task(unsigned int microseconds,
Expand All @@ -258,15 +258,15 @@ class WFTaskFactory
* exceeding target_value. When multiple counters share a same name,
* this operation will be performed on the first created. If no counter
* matches the name, nothing is performed. */
static void count_by_name(const std::string& counter_name)
static int count_by_name(const std::string& counter_name)
{
WFTaskFactory::count_by_name(counter_name, 1);
return WFTaskFactory::count_by_name(counter_name, 1);
}

/* Count by name with a value n. When multiple counters share this name,
* the operation is performed on the counters in the sequence of its
* creation, and more than one counter may reach target value. */
static void count_by_name(const std::string& counter_name, unsigned int n);
static int count_by_name(const std::string& counter_name, unsigned int n);

public:
static WFMailboxTask *create_mailbox_task(void **mailbox,
Expand All @@ -290,13 +290,13 @@ class WFTaskFactory

/* The 'msg' will be sent to the all mailbox tasks under the name, and
* would be lost if no task matched. */
static void send_by_name(const std::string& mailbox_name, void *msg)
static int send_by_name(const std::string& mailbox_name, void *msg)
{
WFTaskFactory::send_by_name(mailbox_name, msg, (size_t)-1);
return WFTaskFactory::send_by_name(mailbox_name, msg, (size_t)-1);
}

static void send_by_name(const std::string& mailbox_name, void *msg,
size_t max);
static int send_by_name(const std::string& mailbox_name, void *msg,
size_t max);

public:
static WFSelectorTask *create_selector_task(size_t candidates,
Expand All @@ -322,13 +322,13 @@ class WFTaskFactory
static WFConditional *create_conditional(const std::string& cond_name,
SubTask *task);

static void signal_by_name(const std::string& cond_name, void *msg)
static int signal_by_name(const std::string& cond_name, void *msg)
{
WFTaskFactory::signal_by_name(cond_name, msg, (size_t)-1);
return WFTaskFactory::signal_by_name(cond_name, msg, (size_t)-1);
}

static void signal_by_name(const std::string& cond_name, void *msg,
size_t max);
static int signal_by_name(const std::string& cond_name, void *msg,
size_t max);

public:
static WFConditional *create_guard(const std::string& resource_name,
Expand Down

0 comments on commit 91f679a

Please sign in to comment.