1#ifndef AWS_COMMON_TASK_SCHEDULER_H
2#define AWS_COMMON_TASK_SCHEDULER_H
3
4/*
5 * Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License").
8 * You may not use this file except in compliance with the License.
9 * A copy of the License is located at
10 *
11 * http://aws.amazon.com/apache2.0
12 *
13 * or in the "license" file accompanying this file. This file is distributed
14 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
15 * express or implied. See the License for the specific language governing
16 * permissions and limitations under the License.
17 */
18
19#include <aws/common/common.h>
20#include <aws/common/linked_list.h>
21#include <aws/common/priority_queue.h>
22
23struct aws_task;
24
25typedef enum aws_task_status {
26 AWS_TASK_STATUS_RUN_READY,
27 AWS_TASK_STATUS_CANCELED,
28} aws_task_status;
29
30/**
31 * A scheduled function.
32 */
33typedef void(aws_task_fn)(struct aws_task *task, void *arg, enum aws_task_status);
34
35/*
36 * A task object.
37 * Once added to the scheduler, a task must remain in memory until its function is executed.
38 */
39struct aws_task {
40 aws_task_fn *fn;
41 void *arg;
42 uint64_t timestamp;
43 struct aws_linked_list_node node;
44 struct aws_priority_queue_node priority_queue_node;
45 const char *type_tag;
46 size_t reserved;
47};
48
49struct aws_task_scheduler {
50 struct aws_allocator *alloc;
51 struct aws_priority_queue timed_queue; /* Tasks scheduled to run at specific times */
52 struct aws_linked_list timed_list; /* If timed_queue runs out of memory, further timed tests are stored here */
53 struct aws_linked_list asap_list; /* Tasks scheduled to run as soon as possible */
54};
55
56AWS_EXTERN_C_BEGIN
57
58/**
59 * Init an aws_task
60 */
61AWS_COMMON_API
62void aws_task_init(struct aws_task *task, aws_task_fn *fn, void *arg, const char *type_tag);
63
64/*
65 * Runs or cancels a task
66 */
67AWS_COMMON_API
68void aws_task_run(struct aws_task *task, enum aws_task_status status);
69
70/**
71 * Initializes a task scheduler instance.
72 */
73AWS_COMMON_API
74int aws_task_scheduler_init(struct aws_task_scheduler *scheduler, struct aws_allocator *alloc);
75
76/**
77 * Empties and executes all queued tasks, passing the AWS_TASK_STATUS_CANCELED status to the task function.
78 * Cleans up any memory allocated, and prepares the instance for reuse or deletion.
79 */
80AWS_COMMON_API
81void aws_task_scheduler_clean_up(struct aws_task_scheduler *scheduler);
82
83AWS_COMMON_API
84bool aws_task_scheduler_is_valid(const struct aws_task_scheduler *scheduler);
85
86/**
87 * Returns whether the scheduler has any scheduled tasks.
88 * next_task_time (optional) will be set to time of the next task, note that 0 will be set if tasks were
89 * added via aws_task_scheduler_schedule_now() and UINT64_MAX will be set if no tasks are scheduled at all.
90 */
91AWS_COMMON_API
92bool aws_task_scheduler_has_tasks(const struct aws_task_scheduler *scheduler, uint64_t *next_task_time);
93
94/**
95 * Schedules a task to run immediately.
96 * The task should not be cleaned up or modified until its function is executed.
97 */
98AWS_COMMON_API
99void aws_task_scheduler_schedule_now(struct aws_task_scheduler *scheduler, struct aws_task *task);
100
101/**
102 * Schedules a task to run at time_to_run.
103 * The task should not be cleaned up or modified until its function is executed.
104 */
105AWS_COMMON_API
106void aws_task_scheduler_schedule_future(
107 struct aws_task_scheduler *scheduler,
108 struct aws_task *task,
109 uint64_t time_to_run);
110
111/**
112 * Removes task from the scheduler and invokes the task with the AWS_TASK_STATUS_CANCELED status.
113 */
114AWS_COMMON_API
115void aws_task_scheduler_cancel_task(struct aws_task_scheduler *scheduler, struct aws_task *task);
116
117/**
118 * Sequentially execute all tasks scheduled to run at, or before current_time.
119 * AWS_TASK_STATUS_RUN_READY will be passed to the task function as the task status.
120 *
121 * If a task schedules another task, the new task will not be executed until the next call to this function.
122 */
123AWS_COMMON_API
124void aws_task_scheduler_run_all(struct aws_task_scheduler *scheduler, uint64_t current_time);
125
126/**
127 * Convert a status value to a c-string suitable for logging
128 */
129AWS_COMMON_API
130const char *aws_task_status_to_c_str(enum aws_task_status status);
131
132AWS_EXTERN_C_END
133
134#endif /* AWS_COMMON_TASK_SCHEDULER_H */
135