1 #ifndef PREFETCH_MANAGER__HPP
2 #define PREFETCH_MANAGER__HPP
3 
4 /*  $Id: prefetch_manager.hpp 574980 2018-11-21 14:24:48Z ucko $
5 * ===========================================================================
6 *
7 *                            PUBLIC DOMAIN NOTICE
8 *               National Center for Biotechnology Information
9 *
10 *  This software/database is a "United States Government Work" under the
11 *  terms of the United States Copyright Act.  It was written as part of
12 *  the author's official duties as a United States Government employee and
13 *  thus cannot be copyrighted.  This software/database is freely available
14 *  to the public for use. The National Library of Medicine and the U.S.
15 *  Government have not placed any restriction on its use or reproduction.
16 *
17 *  Although all reasonable efforts have been taken to ensure the accuracy
18 *  and reliability of the software and data, the NLM and the U.S.
19 *  Government do not and cannot warrant the performance or results that
20 *  may be obtained by using this software or data. The NLM and the U.S.
21 *  Government disclaim all warranties, express or implied, including
22 *  warranties of performance, merchantability or fitness for any particular
23 *  purpose.
24 *
25 *  Please cite the author in any work or product based on this material.
26 *
27 * ===========================================================================
28 *
29 * Author: Eugene Vasilchenko
30 *
31 * File Description:
32 *   Prefetch manager
33 *
34 */
35 
36 #include <corelib/ncbistd.hpp>
37 #include <corelib/ncbiobj.hpp>
38 #include <corelib/ncbithr.hpp>
39 #include <util/thread_pool.hpp>
40 
41 BEGIN_NCBI_SCOPE
42 BEGIN_SCOPE(objects)
43 
44 class CScope;
45 
46 /** @addtogroup ObjectManagerCore
47  *
48  * @{
49  */
50 
51 
52 class CPrefetchRequest;
53 class CPrefetchManager;
54 class CPrefetchManager_Impl;
55 
56 struct SPrefetchTypes
57 {
58     enum EState {
59         eInvalid,   // no prefetch token available
60         eQueued,    // placed in queue
61         eStarted,   // moved from queue to processing
62         eAdvanced,  // got new data while processing
63         eCompleted, // finished processing successfully
64         eCanceled,  // canceled by user request
65         eFailed     // finished processing unsuccessfully
66     };
67     typedef EState EEvent;
68 
69     typedef int TPriority;
70     typedef int TProgress;
71 };
72 
73 
74 class NCBI_XOBJMGR_EXPORT IPrefetchAction : public SPrefetchTypes
75 {
76 public:
77     virtual ~IPrefetchAction(void);
78 
79     virtual bool Execute(CRef<CPrefetchRequest> token) = 0;
80 };
81 
82 
83 class NCBI_XOBJMGR_EXPORT IPrefetchActionSource
84 {
85 public:
86     virtual ~IPrefetchActionSource(void);
87 
88     virtual CIRef<IPrefetchAction> GetNextAction(void) = 0;
89 };
90 
91 
92 class NCBI_XOBJMGR_EXPORT IPrefetchListener : public SPrefetchTypes
93 {
94 public:
95     virtual ~IPrefetchListener(void);
96 
97     virtual void PrefetchNotify(CRef<CPrefetchRequest> token, EEvent event) = 0;
98 };
99 
100 
101 class NCBI_XOBJMGR_EXPORT CPrefetchManager :
102     public CObject,
103     public SPrefetchTypes
104 {
105 public:
106     CPrefetchManager(void);
107     explicit CPrefetchManager(unsigned max_threads,
108                               CThread::TRunMode threads_mode = CThread::fRunDefault);
109     ~CPrefetchManager(void);
110 
111     CRef<CPrefetchRequest> AddAction(TPriority priority,
112                                      IPrefetchAction* action,
113                                      IPrefetchListener* listener = 0);
114     CRef<CPrefetchRequest> AddAction(IPrefetchAction* action,
115                                      IPrefetchListener* listener = 0);
116 
117     // Checks if prefetch is active in current thread.
118     // Throws CPrefetchCanceled exception if the current token is canceled.
119     static bool IsActive(void);
120 
121     // Send cancel requests to all tasks, queued and executing
122     void CancelAllTasks(void);
123 
124     // Clears manager queue and stops all worker threads.
125     void Shutdown(void);
126 
127 private:
128     CRef<CPrefetchManager_Impl> m_Impl;
129 
130 private:
131     CPrefetchManager(const CPrefetchManager&);
132     void operator=(const CPrefetchManager&);
133 };
134 
135 
136 /// This exception is used to report failed actions
137 class NCBI_XOBJMGR_EXPORT CPrefetchFailed : public CException
138 {
139 public:
140     enum EErrCode {
141         eFailed
142     };
143     virtual const char* GetErrCodeString(void) const override;
144     NCBI_EXCEPTION_DEFAULT(CPrefetchFailed,CException);
145 };
146 
147 
148 /// This exception is used to interrupt actions canceled by user
149 class NCBI_XOBJMGR_EXPORT CPrefetchCanceled : public CException
150 {
151 public:
152     enum EErrCode {
153         eCanceled
154     };
155     virtual const char* GetErrCodeString(void) const override;
156     NCBI_EXCEPTION_DEFAULT(CPrefetchCanceled,CException);
157 };
158 
159 
160 class NCBI_XOBJMGR_EXPORT CPrefetchSequence : public CObject
161 {
162 public:
163     CPrefetchSequence(CPrefetchManager& manager,
164                       IPrefetchActionSource* source,
165                       size_t active_size = 10);
166     ~CPrefetchSequence(void);
167 
168     /// Returns next action waiting for its result if necessary
169     CRef<CPrefetchRequest> GetNextToken(void);
170 
171 protected:
172     void EnqueNextAction(void);
173 
174 private:
175     CRef<CPrefetchManager>          m_Manager;
176     CIRef<IPrefetchActionSource>    m_Source;
177     CMutex                          m_Mutex;
178     list< CRef<CPrefetchRequest> >  m_ActiveTokens;
179 };
180 
181 
182 class NCBI_XOBJMGR_EXPORT CPrefetchRequest
183     : public CThreadPool_Task,
184       public SPrefetchTypes
185 {
186 public:
187     CPrefetchRequest(CObjectFor<CMutex>* state_mutex,
188                      IPrefetchAction* action,
189                      IPrefetchListener* listener,
190                      unsigned int priority);
191     ~CPrefetchRequest(void);
192 
GetAction(void) const193     IPrefetchAction* GetAction(void) const
194         {
195             return m_Action.GetNCPointer();
196         }
197 
GetListener(void) const198     IPrefetchListener* GetListener(void) const
199         {
200             return m_Listener.GetNCPointerOrNull();
201         }
202     void SetListener(IPrefetchListener* listener);
203 
204     EState GetState(void) const;
205 
206     // in one of final states: completed, failed, canceled
IsDone(void) const207     bool IsDone(void) const
208         {
209             return IsFinished();
210         }
211 
GetProgress(void) const212     TProgress GetProgress(void) const
213         {
214             return m_Progress;
215         }
216     TProgress SetProgress(TProgress progress);
217 
218     virtual EStatus Execute(void);
219 
220     virtual void OnStatusChange(EStatus /* old */);
221 
222 private:
223     friend class CPrefetchManager;
224     friend class CPrefetchManager_Impl;
225 
226     // back references
227     CRef<CObjectFor<CMutex> >   m_StateMutex;
228 
229     CIRef<IPrefetchAction>      m_Action;
230     CIRef<IPrefetchListener>    m_Listener;
231     TProgress                   m_Progress;
232 };
233 
234 
235 /* @} */
236 
237 
238 END_SCOPE(objects)
239 END_NCBI_SCOPE
240 
241 #endif  // PREFETCH_MANAGER__HPP
242