Add return value for WFTaskFactory::XXXX_by_name(). (#1627)

* Add return value for WFTaskFactory::XXXX_by_name().

* Update about-counter.md

* Update about-timer.md
This commit is contained in:
xiehan
2024-09-24 23:35:09 +08:00
committed by GitHub
parent 9420446118
commit 91f679ad1c
4 changed files with 52 additions and 35 deletions

View File

@@ -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操作可能让多个计数器达到目标值。
# 命名计数器详细行为定义

View File

@@ -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)。
@@ -35,7 +35,8 @@ public:
如果在创建定时器任务时传入一个名称,那么这个定时器就可以在被提前中断。
中断一个定时任务的方法是通过WFTaskFactory::cancel_by_name这个接口这个接口默认情况下会取消这个名称下的所有定时器。
因此我们也支持传入一个max参数让操作最多取消max个定时器。当然如果没有这个名称下的定时器cancel操作不会产生任何效果
因此我们也支持传入一个max参数让操作最多取消max个定时器。无论哪个接口,返回值都是代表实际被取消的定时器个数
如果没有这个名称下的定时器cancel操作不会产生任何效果并返回0。
定时器在被创建之后就可取消,并非一定要等它被启动之后。以这个代码为例:
~~~cpp
#include <stdio.h>

View File

@@ -161,7 +161,7 @@ public:
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_;
@@ -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);
@@ -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_);
@@ -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,
@@ -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 ******************/
@@ -342,7 +345,7 @@ public:
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)
@@ -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);
@@ -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,
@@ -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 ******************/
@@ -521,7 +528,7 @@ public:
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)
@@ -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);
@@ -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,
@@ -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 ******************/
@@ -705,7 +716,7 @@ public:
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);
@@ -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);
@@ -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,
@@ -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 ******************/

View File

@@ -228,13 +228,13 @@ public:
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,
@@ -258,15 +258,15 @@ public:
* 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,
@@ -290,13 +290,13 @@ public:
/* 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,
@@ -322,13 +322,13 @@ public:
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,