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 class TaskletScheduler; 49 50 /** 51 * @addtogroup core-tasklet 52 * 53 * @brief 54 * This module includes definitions for tasklets and the tasklet scheduler. 55 * 56 * @{ 57 * 58 */ 59 60 /** 61 * This class is used to represent a tasklet. 62 * 63 */ 64 class Tasklet : public InstanceLocator 65 { 66 public: 67 /** 68 * This class implements the tasklet scheduler. 69 * 70 */ 71 class Scheduler : private NonCopyable 72 { 73 friend class Tasklet; 74 75 public: 76 /** 77 * This constructor initializes the object. 78 * 79 */ Scheduler(void)80 Scheduler(void) 81 : mTail(nullptr) 82 { 83 } 84 85 /** 86 * This method indicates whether or not there are tasklets pending. 87 * 88 * @retval TRUE If there are tasklets pending. 89 * @retval FALSE If there are no tasklets pending. 90 * 91 */ AreTaskletsPending(void) const92 bool AreTaskletsPending(void) const { return mTail != nullptr; } 93 94 /** 95 * This method processes all tasklets queued when this is called. 96 * 97 */ 98 void ProcessQueuedTasklets(void); 99 100 private: 101 void PostTasklet(Tasklet &aTasklet); 102 103 Tasklet *mTail; // A circular singly linked-list 104 }; 105 106 /** 107 * This function reference is called when the tasklet is run. 108 * 109 * @param[in] aTasklet A reference to the tasklet being run. 110 * 111 */ 112 typedef void (&Handler)(Tasklet &aTasklet); 113 114 /** 115 * This constructor creates a tasklet instance. 116 * 117 * @param[in] aInstance A reference to the OpenThread instance object. 118 * @param[in] aHandler A pointer to a function that is called when the tasklet is run. 119 * 120 */ Tasklet(Instance & aInstance,Handler aHandler)121 Tasklet(Instance &aInstance, Handler aHandler) 122 : InstanceLocator(aInstance) 123 , mHandler(aHandler) 124 , mNext(nullptr) 125 { 126 } 127 128 /** 129 * This method puts the tasklet on the tasklet scheduler run queue. 130 * 131 * If the tasklet is already posted, no change is made and run queue stays as before. 132 * 133 */ 134 void Post(void); 135 136 /** 137 * This method indicates whether the tasklet is posted or not. 138 * 139 * @retval TRUE The tasklet is posted. 140 * @retval FALSE The tasklet is not posted. 141 * 142 */ IsPosted(void) const143 bool IsPosted(void) const { return (mNext != nullptr); } 144 145 private: RunTask(void)146 void RunTask(void) { mHandler(*this); } 147 148 Handler mHandler; 149 Tasklet *mNext; 150 }; 151 152 /** 153 * This class defines a tasklet that also maintains a user context pointer. 154 * 155 * In typical `Tasklet` use, in the handler callback, the owner of the tasklet is determined using `GetOwner<Type>` 156 * method. This method works if there is a single instance of `Type` within OpenThread instance hierarchy. The 157 * `TaskletContext` is intended for cases where there may be multiple instances of the same class/type using a `Tasklet` 158 * object. `TaskletContext` will store a context `void *` information. 159 * 160 */ 161 class TaskletContext : public Tasklet 162 { 163 public: 164 /** 165 * This constructor creates a tasklet instance. 166 * 167 * @param[in] aInstance A reference to the OpenThread instance. 168 * @param[in] aHandler A pointer to a function that is called when the tasklet is run. 169 * @param[in] aContext A pointer to an arbitrary context information. 170 * 171 */ TaskletContext(Instance & aInstance,Handler aHandler,void * aContext)172 TaskletContext(Instance &aInstance, Handler aHandler, void *aContext) 173 : Tasklet(aInstance, aHandler) 174 , mContext(aContext) 175 { 176 } 177 178 /** 179 * This method returns the pointer to the arbitrary context information. 180 * 181 * @returns Pointer to the arbitrary context information. 182 * 183 */ GetContext(void)184 void *GetContext(void) { return mContext; } 185 186 private: 187 void *mContext; 188 }; 189 190 /** 191 * @} 192 * 193 */ 194 195 } // namespace ot 196 197 #endif // TASKLET_HPP_ 198