14035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
24035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *
34035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * Redistribution and use in source and binary forms, with or without
44035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * modification, are permitted provided that the following conditions are
54035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * met:
64035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *     * Redistributions of source code must retain the above copyright
74035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *       notice, this list of conditions and the following disclaimer.
84035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *     * Redistributions in binary form must reproduce the above
94035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *       copyright notice, this list of conditions and the following
104035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *       disclaimer in the documentation and/or other materials provided
114035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *       with the distribution.
124035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *     * Neither the name of The Linux Foundation, nor the names of its
134035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *       contributors may be used to endorse or promote products derived
144035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *       from this software without specific prior written permission.
154035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *
164035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
174035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
184035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
194035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
204035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
214035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
224035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
234035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
244035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
254035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
264035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
274035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin *
284035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin */
294035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin#ifndef __LOC_THREAD__
304035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin#define __LOC_THREAD__
314035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
324035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin#include <stddef.h>
334035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin#include <pthread.h>
344035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
354035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin// abstract class to be implemented by client to provide a runnable class
364035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin// which gets scheduled by LocThread
374035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinclass LocRunnable {
384035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinpublic:
394035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    inline LocRunnable() {}
404035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    inline virtual ~LocRunnable() {}
414035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
424035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    // The method to be implemented by thread clients
434035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    // and be scheduled by LocThread
444035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    // This method will be repeated called until it returns false; or
454035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    // until thread is stopped.
464035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    virtual bool run() = 0;
474035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
484035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    // The method to be run before thread loop (conditionally repeatedly)
494035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    // calls run()
504035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    inline virtual void prerun() {}
514035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
524035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    // The method to be run after thread loop (conditionally repeatedly)
534035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    // calls run()
544035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    inline virtual void postrun() {}
554035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin};
564035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
574035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin// opaque class to provide service implementation.
584035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinclass LocThreadDelegate;
594035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
604035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin// A utility class to create a thread and run LocRunnable
614035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin// caller passes in.
624035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinclass LocThread {
634035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    LocThreadDelegate* mThread;
644035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjinpublic:
654035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    inline LocThread() : mThread(NULL) {}
664035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    virtual ~LocThread();
674035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
684035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    typedef pthread_t (*tCreate)(const char* name, void* (*start)(void*), void* arg);
694035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    // client starts thread with a runnable, which implements
704035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    // the logics to fun in the created thread context.
714035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    // The thread could be either joinable or detached.
724035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    // runnable is an obj managed by client. Client creates and
734035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    //          frees it (but must be after stop() is called, or
744035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    //          this LocThread obj is deleted).
754035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    //          The obj will be deleted by LocThread if start()
764035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    //          returns true. Else it is client's responsibility
774035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    //          to delete the object
784035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    // Returns 0 if success; false if failure.
794035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    bool start(tCreate creator, const char* threadName, LocRunnable* runnable, bool joinable = true);
804035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    inline bool start(const char* threadName, LocRunnable* runnable, bool joinable = true) {
814035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin        return start(NULL, threadName, runnable, joinable);
824035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    }
834035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
844035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    // NOTE: if this is a joinable thread, this stop may block
854035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    // for a while until the thread is joined.
864035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    void stop();
874035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
884035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    // thread status check
894035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin    inline bool isRunning() { return NULL != mThread; }
904035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin};
914035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin
924035be28a255eaa5605dbd9abeb2340db584249cPatrick Tjin#endif //__LOC_THREAD__
93