• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2016, The OpenThread Authors.
3  *  All rights reserved.
4  *
5  *  Redistribution and use in source and binary forms, with or without
6  *  modification, are permitted provided that the following conditions are met:
7  *  1. Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  *  2. Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *  3. Neither the name of the copyright holder nor the
13  *     names of its contributors may be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  *  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  *  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20  *  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  *  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  *  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  *  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  *  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  *  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  *  POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /**
30  * @file
31  *   This file includes definitions for tasklets and the tasklet scheduler.
32  */
33 
34 #ifndef TASKLET_HPP_
35 #define TASKLET_HPP_
36 
37 #include "openthread-core-config.h"
38 
39 #include <stdio.h>
40 
41 #include <openthread/tasklet.h>
42 
43 #include "common/locator.hpp"
44 #include "common/non_copyable.hpp"
45 
46 namespace ot {
47 
48 /**
49  * @addtogroup core-tasklet
50  *
51  * @brief
52  *   This module includes definitions for tasklets and the tasklet scheduler.
53  *
54  * @{
55  */
56 
57 /**
58  * Is used to represent a tasklet.
59  */
60 class Tasklet : public InstanceLocator
61 {
62 public:
63     /**
64      * Implements the tasklet scheduler.
65      */
66     class Scheduler : private NonCopyable
67     {
68         friend class Tasklet;
69 
70     public:
71         /**
72          * Initializes the object.
73          */
Scheduler(void)74         Scheduler(void)
75             : mTail(nullptr)
76         {
77         }
78 
79         /**
80          * Indicates whether or not there are tasklets pending.
81          *
82          * @retval TRUE   If there are tasklets pending.
83          * @retval FALSE  If there are no tasklets pending.
84          */
AreTaskletsPending(void) const85         bool AreTaskletsPending(void) const { return mTail != nullptr; }
86 
87         /**
88          * Processes all tasklets queued when this is called.
89          */
90         void ProcessQueuedTasklets(void);
91 
92     private:
93         void PostTasklet(Tasklet &aTasklet);
94         void RemoveTasklet(Tasklet &aTasklet);
95 
96         Tasklet *mTail; // A circular singly linked-list
97     };
98 
99     /**
100      * Reference is called when the tasklet is run.
101      *
102      * @param[in]  aTasklet  A reference to the tasklet being run.
103      */
104     typedef void (&Handler)(Tasklet &aTasklet);
105 
106     /**
107      * Creates a tasklet instance.
108      *
109      * @param[in]  aInstance   A reference to the OpenThread instance object.
110      * @param[in]  aHandler    A pointer to a function that is called when the tasklet is run.
111      */
Tasklet(Instance & aInstance,Handler aHandler)112     Tasklet(Instance &aInstance, Handler aHandler)
113         : InstanceLocator(aInstance)
114         , mHandler(aHandler)
115         , mNext(nullptr)
116     {
117     }
118 
119     /**
120      * Puts the tasklet on the tasklet scheduler run queue.
121      *
122      * If the tasklet is already posted, no change is made and run queue stays as before.
123      */
124     void Post(void);
125 
126     /**
127      * Removes the tasklet from the tasklet scheduler run queue.
128      *
129      * If the tasklet is not posted, no change is made and run queue stays as before.
130      */
131     void Unpost(void);
132 
133     /**
134      * Indicates whether the tasklet is posted or not.
135      *
136      * @retval TRUE  The tasklet is posted.
137      * @retval FALSE The tasklet is not posted.
138      */
IsPosted(void) const139     bool IsPosted(void) const { return (mNext != nullptr); }
140 
141 private:
RunTask(void)142     void RunTask(void) { mHandler(*this); }
143 
144     Handler  mHandler;
145     Tasklet *mNext;
146 };
147 
148 /**
149  * Defines a tasklet owned by specific type and using a method on owner type as the callback.
150  *
151  * @tparam Owner              The type of owner of this tasklet.
152  * @tparam HandleTaskletPtr   A pointer to a non-static member method of `Owner` to use as tasklet handler.
153  *
154  * The `Owner` MUST be a type that is accessible using `InstanceLocator::Get<Owner>()`.
155  */
156 template <typename Owner, void (Owner::*HandleTaskletPtr)(void)> class TaskletIn : public Tasklet
157 {
158 public:
159     /**
160      * Initializes the tasklet.
161      *
162      * @param[in]  aInstance   The OpenThread instance.
163      */
TaskletIn(Instance & aInstance)164     explicit TaskletIn(Instance &aInstance)
165         : Tasklet(aInstance, HandleTasklet)
166     {
167     }
168 
169 private:
170     static void HandleTasklet(Tasklet &aTasklet); // Implemented in `instance.hpp`
171 };
172 
173 /**
174  * Defines a tasklet that also maintains a user context pointer.
175  *
176  * In typical `Tasklet` use, in the handler callback, the owner of the tasklet is determined using `GetOwner<Type>`
177  * method. This method works if there is a single instance of `Type` within OpenThread instance hierarchy. The
178  * `TaskletContext` is intended for cases where there may be multiple instances of the same class/type using a `Tasklet`
179  * object. `TaskletContext` will store a context `void *` information.
180  */
181 class TaskletContext : public Tasklet
182 {
183 public:
184     /**
185      * Creates a tasklet instance.
186      *
187      * @param[in]  aInstance   A reference to the OpenThread instance.
188      * @param[in]  aHandler    A pointer to a function that is called when the tasklet is run.
189      * @param[in]  aContext    A pointer to an arbitrary context information.
190      */
TaskletContext(Instance & aInstance,Handler aHandler,void * aContext)191     TaskletContext(Instance &aInstance, Handler aHandler, void *aContext)
192         : Tasklet(aInstance, aHandler)
193         , mContext(aContext)
194     {
195     }
196 
197     /**
198      * Returns the pointer to the arbitrary context information.
199      *
200      * @returns Pointer to the arbitrary context information.
201      */
GetContext(void)202     void *GetContext(void) { return mContext; }
203 
204 private:
205     void *mContext;
206 };
207 
208 /**
209  * @}
210  */
211 
212 } // namespace ot
213 
214 #endif // TASKLET_HPP_
215