NCBI C++ ToolKit
psgs_uv_loop_binder.hpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 #ifndef PSGS_UV_LOOP_BINDER__HPP
2 #define PSGS_UV_LOOP_BINDER__HPP
3 
4 /* $Id: psgs_uv_loop_binder.hpp 98308 2022-10-26 17:48:52Z satskyse $
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  * Authors: Sergey Satskiy
30  *
31  * File Description: PSG main uv loop binder which lets to invoke a callback
32  * from within a uv main loop
33  *
34  */
35 
36 #include <uv.h>
37 
38 #include <functional>
39 #include <mutex>
40 #include <list>
41 using namespace std;
42 
43 #include "psgs_io_callbacks.hpp"
44 
45 // libuv offers two places for the callbacks:
46 // - prepare (before io)
47 // - check (after io)
48 // The define below switches between prepare and check callback
49 // Note: it is possible to add a feature of the runtime switch between these
50 // callbacks (an argument for the binding)
51 #define USE_PREPARE_CB 0
52 
53 
54 // The class provides ability to setup a callback which will be invoked from
55 // the libuv event loop.
56 // The design idea is that there is a protected queue of the callbacks which
57 // should be invoked from the libuv event loop. When the users postpone their
58 // callbacks it essentially leads to two actions:
59 // - memorize the callback in the protected queue
60 // - send the libuv async message to wakeup libuv if it is waiting on something
61 // Then there is as well a prepare callback setup for libuv once at the very
62 // beginning of the server lifetime. The prepare callback is invoked when libuv
63 // is woken up by an async message. The responsibility of the prepare callback
64 // is to check the callback queue and invoke the stored callbacks.
65 //
66 // The drawback is that the prepare callback is called once per libuv event
67 // loop. However it should not affect the performance severely.
68 //
69 // The async message cannot be used alone because there is no guarantee that
70 // its callback will be called exactly once per uv_async_send()
71 // See more info here:
72 // https://stackoverflow.com/questions/18130724/libuv-uv-check-t-and-uv-prepare-t-usage
74 {
75  public:
76  using TProcessorCB = function<void(void * user_data)>;
77 
78  public:
79  CPSGS_UvLoopBinder(uv_loop_t * loop);
81 
82  // The provided callback will be invoked from the libuv event loop.
83  // The invokation will happened once.
84  // The method is thread safe.
85  void PostponeInvoke(TProcessorCB cb, void * user_data);
86 
87  // The provided callback will be invoked from the libuv event loop.
88  // The invokation will happened once.
89  // The method is thread safe.
90  void PostponeInvoke(TProcessorCB cb, void * user_data, size_t request_id);
91 
92  void SetSocketCallback(int fd,
94  uint64_t timeout_millisec,
95  void * user_data,
99  size_t request_id);
100  void DismissSocketIOCallback(CPSGS_SocketIOCallback * callback);
101 
102  public:
103  // Internal usage only.
104  // The libuv C-style callback calls this method upon the prepare
105  // callback
106  void x_UvOnCallback(void);
107 
108  uv_loop_t * GetUvLoop(void) const
109  {
110  return m_Loop;
111  }
112 
113  void x_Unregister(void);
114 
115  private:
117  {
118  SUserCallback(void * user_data, TProcessorCB cb, size_t request_id) :
119  m_FromProcessor(true), m_RequestId(request_id),
120  m_UserData(user_data), m_ProcCallback(cb)
121  {}
122 
123  SUserCallback(void * user_data, TProcessorCB cb) :
124  m_FromProcessor(false), m_RequestId(0),
125  m_UserData(user_data), m_ProcCallback(cb)
126  {}
127 
129  size_t m_RequestId;
130  void * m_UserData;
132  };
133 
134  private:
135  #if USE_PREPARE_CB
136  uv_prepare_t m_Prepare;
137  #else
138  uv_check_t m_Check;
139  #endif
140 
141  uv_loop_t * m_Loop;
142  uv_async_t m_Async;
143 
144  mutex m_QueueLock;
145  list<SUserCallback> m_Callbacks;
146 
148  list<CPSGS_SocketIOCallback *> m_SocketIOCallbacks;
149 };
150 
151 
152 #endif // PSGS_UV_LOOP_BINDER__HPP
153 
function< EPSGS_PollContinue(void *user_data)> TEventCB
function< EPSGS_PollContinue(void *user_data)> TTimeoutCB
function< EPSGS_PollContinue(const string &message, void *user_data)> TErrorCB
function< void(void *user_data)> TProcessorCB
list< SUserCallback > m_Callbacks
list< CPSGS_SocketIOCallback * > m_SocketIOCallbacks
uv_loop_t * GetUvLoop(void) const
#define true
Definition: bool.h:35
#define false
Definition: bool.h:36
Uint8 uint64_t
SUserCallback(void *user_data, TProcessorCB cb, size_t request_id)
SUserCallback(void *user_data, TProcessorCB cb)
Modified on Sun Apr 14 05:29:20 2024 by modify_doxy.py rev. 669887