1 /*
2  * workqueue.h, workqueue class
3  *
4  * Copyright (c) 2009-2010 Wind River Systems, Inc.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 
19 #ifndef __WORKQUEUE_H
20 #define __WORKQUEUE_H
21 
22 #include <pthread.h>
23 #include <list.h>
24 
25 #include <thread.h>
26 
27 class WorkableInterface {
28 public:
~WorkableInterface()29     virtual ~WorkableInterface() {};
30 
31     virtual void Work(void) = 0;
32 };
33 
34 class WorkQueue : public Thread, public WorkableInterface
35 {
36 public:
37     WorkQueue();
38     /*
39      * if WorkQueue has the pending works not proccessed yet,
40      * WorkQueue::Run() calls its own Work() instead of the derived class's.
41      * becaused a derived class does not exist.
42      */
43     ~WorkQueue();
44 
45     /* start & stop & pause & resume work thread */
46     int StartWork(bool executing);
47     void StopWork(void);
48     void PauseWork(void);
49     void ResumeWork(void);
50 
51     /* the class inheriting WorkQueue uses this method */
52     void ScheduleWork(void);
53     /* the class implementing WorkableInterface uses this method */
54     void ScheduleWork(WorkableInterface *wi);
55     /*
56      * FIXME (BUG)
57      *  must be called before the class implementing WorkableInterface or
58      *  inheriting WorkQueue is destructed,
59      *  and don't call ScheduleWork() anymore right before destructing
60      *  the class.
61      */
62     void FlushWork(void);
63     /* remove all scheduled works matched with wi from workqueue list */
64     void CancelScheduledWork(WorkableInterface *wi);
65 
66 private:
67     /* inner class for flushing */
68     class FlushBarrier : public WorkableInterface
69     {
70     public:
71         FlushBarrier();
72         ~FlushBarrier();
73 
74         /*
75          * FIXME (BUG)
76          *  it has a potential bug that signal() could be called earlier
77          *  than wait() could be.
78          */
79         void WaitCompletion(void);
80 
81     private:
82         virtual void Work(void); /* WorkableInterface */
83 
84         pthread_mutex_t cplock;
85         pthread_cond_t complete;
86     };
87 
88     virtual void Run(void); /* RunnableInterface */
89 
90     /* overriden by the class inheriting WorkQueue class */
91     virtual void Work(void); /* WorkableInterface */
92 
93     /*
94      * FIXME (BUG)
95      *  if a class implementing WorkableInterface disapears earlier
96      *  than WorkQueue then wi is not valid anymore and causes fault.
97      */
98     void DoWork(WorkableInterface *wi);
99 
100     struct list *works;
101     pthread_mutex_t wlock;
102     pthread_cond_t wcond;
103 
104     /* executing & pause */
105     bool wait_for_works;
106     bool executing;
107 
108     pthread_mutex_t executing_lock;
109     pthread_cond_t executing_wait;
110     pthread_cond_t paused_wait;
111 
112     int stop;
113 };
114 
115 #endif /* __WORKQUEUE_H */
116