/** * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef MOCK_RIL_WORKER_H_ #define MOCK_RIL_WORKER_H_ #include <queue> #include <list> #include <vector> #include <pthread.h> #include <cutils/atomic.h> #include <utils/SystemClock.h> /** * A Thread class. * * 0) Extend WorkerThread creating a Worker method which * monitors isRunning(). For example: * * void * Worker(void *param) { * while (isRunning() == 0) { * pthread_mutex_lock(&mutex_); * while (isRunning() && !SOME-CONDITION) { * pthread_cond_wait(&cond_, &mutex_); * } * if (isRunning()) { * DO-WORK * } else { * pthread_mutex_unlock(&mutex_); * } * } * return NULL; * } * * 1) Create the WorkerThread. * 2) Execute Run passing a param which will be passed to Worker. * 3) Call Stop() or destroy the thread to stop processing. * */ class WorkerThread { protected: pthread_attr_t attr_; pthread_mutex_t mutex_; pthread_cond_t cond_; pthread_t tid_; void *workerParam_; #define STATE_INITIALIZED 1 #define STATE_RUNNING 2 #define STATE_STOPPING 3 #define STATE_STOPPED 4 int32_t state_; static void * Work(void *param); virtual bool isRunning(); public: WorkerThread(); virtual ~WorkerThread(); // Return true if changed from STATE_RUNNING to STATE_STOPPING virtual bool BeginStopping(); // Wait until state is not STATE_STOPPING virtual void WaitUntilStopped(); virtual void Stop(); virtual int Run(void *workerParam); /** * Method called to do work, see example above. * While running isRunning() must be monitored. */ virtual void *Worker(void *) = 0; }; /** * A WorkerQueue. * * 0) Extend overriding Process * 1) Create an instance * 2) Call Run. * 3) Call Add, passing a pointer which is added to a queue * 4) Process will be called with a pointer as work can be done. */ class WorkerQueue { private: friend class WorkerQueueThread; struct Record { int64_t time; void *p; }; class record_compare { public: // To get ascending order return true if lhs > rhs. bool operator() (const struct Record* lhs, const struct Record* rhs) const { return lhs->time > rhs->time; } }; std::list<struct Record *> q_; // list of records to be processed std::list<struct Record *> free_list_; // list of records that have been released std::priority_queue<struct Record *, std::vector<struct Record *>, record_compare> delayed_q_; // list of records that are delayed class WorkerQueueThread *wqt_; protected: struct Record *obtain_record(void *p, int delay_in_ms); void release_record(struct Record *r); public: WorkerQueue(); virtual ~WorkerQueue(); int Run(); void Stop(); void Add(void *p); void AddDelayed(void *p, int delay_in_ms); virtual void Process(void *) = 0; }; extern void testWorker(); #endif // MOCK_RIL_WORKER_H_