event_loop.h revision f7914d0fbadf2644c0c4096380c741bee2a026e0
1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#ifndef CHRE_CORE_EVENT_LOOP_H_ 18#define CHRE_CORE_EVENT_LOOP_H_ 19 20// TODO: using std lib for initial test... we can't do this in the real world 21#include <atomic> 22#include <vector> 23 24#include "chre/core/event.h" 25#include "chre/core/nanoapp.h" 26#include "chre/util/blocking_queue.h" 27#include "chre/util/non_copyable.h" 28#include "chre/util/synchronized_memory_pool.h" 29 30namespace chre { 31 32/** 33 * TODO: document this better 34 */ 35class EventLoop : public NonCopyable { 36 public: 37 // TODO: need a clear delineation for which methods are safe to call from 38 // threads other than the one calling run()... should include stop() and 39 // postEvent()... everything else would decidedly be not thread-safe 40 41 /** 42 * Starts a nanoapp by invoking the start entry point. If this is successful, 43 * the app is managed by the event loop and the pointer passed in must remain 44 * valid. 45 * 46 * @param A pointer to the nanoapp to start. 47 * @return True if the app was started successfully. 48 */ 49 bool startNanoapp(Nanoapp *nanoapp); 50 51 /** 52 * Stops a nanoapp by invoking the stop entry point. The nanoapp passed in 53 * must have been previously started by the startNanoapp method. 54 * 55 * @param A pointer to the nanoapp to stop. 56 */ 57 void stopNanoapp(Nanoapp *nanoapp); 58 59 /** 60 * Start the main task run loop. Only returns after stop() is called 61 * (from another context). 62 */ 63 void run(); 64 65 /** 66 * Signals the event loop currently executing in run() to exit gracefully at 67 * the next available opportunity. 68 */ 69 void stop(); 70 71 /** 72 * Posts an event to a nanoapp that is currently running (or all nanoapps if 73 * the broadcast instance ID is used). 74 * 75 * @param The type of data being posted. 76 * @param The data being posted. 77 * @param The callback to invoke when the event is no longer needed. 78 * @param The instance ID of the sender of this event. 79 * @param The instance ID of the destination of this event. 80 * 81 * TODO: this is safe to call from other threads, and posts to the incoming 82 * event queue, then it is doled out to interested nanoapp queues later 83 */ 84 void postEvent(uint16_t eventType, void *eventData, 85 chreEventCompleteFunction *freeCallback, 86 uint32_t senderInstanceId = kSystemInstanceId, 87 uint32_t targetInstanceId = kBroadcastInstanceId); 88 89 // TODO: static method that allocates + constructs + posts an Event to all 90 // EventLoops (i.e. just the one for now), to simplify external code that will 91 // call this (they don't need to worry about how events are allocated, etc) 92 93 // TODO: do we need this? it might be a helpful convenience function that 94 // handles creation of a timer and stuff 95 void postEventDelayed(Event *event, uint64_t delayNs); 96 97 /** 98 * Returns a pointer to the currently executing Nanoapp, or nullptr if none is 99 * currently executing. 100 * 101 * @return a pointer to the currently executing nanoapp and nullptr if not 102 * currently in an app context. 103 */ 104 const Nanoapp *getCurrentNanoapp() const; 105 106 /** 107 * Returns a guaranteed unique instance ID that can be used to construct a 108 * nanoapp. 109 * 110 * @return a unique instance ID to assign to a nanoapp. 111 */ 112 uint32_t getNextInstanceId(); 113 114 private: 115 //! The maximum number of events that can be active in the system. 116 static constexpr size_t kMaxEventCount = 1024; 117 118 //! The instance ID that was previously generated by getNextInstanceId. 119 uint32_t mLastInstanceId = kSystemInstanceId; 120 121 //! The memory pool to allocate incoming events from. 122 SynchronizedMemoryPool<Event, kMaxEventCount> mEventPool; 123 124 // TODO: replace STL use with our own data structures 125 std::vector<Nanoapp*> mNanoapps; 126 BlockingQueue<Event*> mEvents; 127 128 // TODO: we probably want our own atomic platform abstraction too 129 std::atomic<bool> mRunning{false}; 130 131 Nanoapp *mCurrentApp = nullptr; 132 133 void freeEvent(Event *event); 134 Nanoapp *lookupAppByInstanceId(uint32_t instanceId); 135 136 // TODO: we probably want a to model kSystemInstanceId as an actual nanoapp 137 // with entry points and all that to make it simpler to post events to ourself 138 // and the like... 139}; 140 141} // namespace chre 142 143#endif // CHRE_CORE_EVENT_LOOP_H_ 144