VSM C++ SDK
Vehicle Specific Modules SDK
request_container.h
Go to the documentation of this file.
1 // Copyright (c) 2014, Smart Projects Holdings Ltd
2 // All rights reserved.
3 // See LICENSE file for license details.
4 
11 #ifndef TASK_CONTAINER_H_
12 #define TASK_CONTAINER_H_
13 
14 #include <ugcs/vsm/callback.h>
15 #include <ugcs/vsm/utils.h>
16 
17 #include <memory>
18 #include <mutex>
19 #include <chrono>
20 #include <condition_variable>
21 #include <atomic>
22 #include <list>
23 #include <atomic>
24 
25 namespace ugcs {
26 namespace vsm {
27 
31 class Request_container: public std::enable_shared_from_this<Request_container> {
33 public:
37  class Request: public std::enable_shared_from_this<Request> {
38  DEFINE_COMMON_CLASS(Request, Request)
39  public:
43  enum class Status {
47  PENDING,
51  CANCELLATION_PENDING,
55  CANCELING,
59  PROCESSING,
68  ABORT_PENDING,
71  ABORTED,
72 
76  RESULT_CODES,
77 
79  OK = RESULT_CODES,
81  CANCELED
82  };
83 
87  typedef std::unique_lock<std::mutex> Locker;
88 
89  virtual
90  ~Request();
91 
98  void
99  Set_processing_handler(const Handler &handler);
100 
102  void
103  Set_processing_handler(Handler &&handler);
104 
112  void
113  Set_completion_handler(const Request_container::Ptr &context,
114  const Handler &handler);
115 
117  void
118  Set_completion_handler(const Request_container::Ptr &context,
119  Handler &&handler);
120 
136  void
137  Set_cancellation_handler(const Handler &handler);
138 
140  void
141  Set_cancellation_handler(Handler &&handler);
142 
150  void
151  Set_done_handler(Handler &handler);
152 
154  void
155  Set_done_handler(Handler &&handler);
156 
161  Get_completion_context(Locker locker = Locker()) const;
162 
172  void
173  Process(bool process_request);
174 
186  void
187  Complete(Status status = Status::OK, Locker locker = Locker());
188 
197  void
198  Cancel(Locker locker = Locker());
199 
210  void
211  Abort(Locker locker = Locker());
212 
222  Locker
223  Lock(bool acquire = true) const;
224 
226  Status
227  Get_status() const
228  {
229  return status;
230  }
231 
233  bool
234  Is_completed() const
235  {
236  return status >= Status::RESULT_CODES;
237  }
238 
242  bool
244  {
245  /* Abort pending is only for completion contexts. */
246  return !Is_completed() && Get_status() != Status::ABORT_PENDING;
247  }
248 
250  bool
251  Is_aborted() const
252  {
253  return status == Status::ABORTED || status == Status::ABORT_PENDING;
254  }
255 
257  bool
259  {
260  return status == Status::PROCESSING;
261  }
262 
264  bool
266  {
267  return completion_delivered;
268  }
269 
273  bool
275  {
276  return completion_processed && !completion_handler;
277  }
278 
282  bool
283  Is_done() const
284  {
285  return Is_completion_delivered() || Is_aborted();
286  }
287 
299  bool
300  Wait_done(bool process_ctx = true,
301  std::chrono::milliseconds timeout = std::chrono::milliseconds::zero());
302 
304  bool&
306  {
307  return timed_out;
308  }
309 
310  protected:
314  virtual void
315  Destroy();
316 
323  bool
324  Is_completion_handler_present();
325 
326  private:
328  Handler processing_handler;
330  Handler completion_handler;
334  Handler cancellation_handler;
338  Handler done_handler;
340  Request_container::Ptr completion_context;
345  bool timed_out = false;
346  std::atomic<Status> status = { Status::PENDING };
348  std::atomic_bool completion_processed = { false },
350  completion_delivered = { false };
352  mutable std::mutex mutex;
354  std::condition_variable cond_var;
355  };
356 
360  class Request_waiter: public std::enable_shared_from_this<Request_waiter> {
362  public:
366  typedef Callback_base<bool>::Ptr<> Predicate;
367 
368  class Locker;
369 
371  virtual void
372  Notify();
373 
375  Locker
376  Lock();
377 
383  Locker
384  Lock_notify();
385 
399  int
400  Wait_and_process(const std::initializer_list<Request_container::Ptr> &containers,
401  std::chrono::milliseconds timeout = std::chrono::milliseconds::zero(),
402  int requests_limit = 0, Predicate predicate = Predicate());
403 
417  int
418  Wait_and_process(const std::list<Request_container::Ptr> &containers,
419  std::chrono::milliseconds timeout = std::chrono::milliseconds::zero(),
420  int requests_limit = 0, Predicate predicate = Predicate());
421 
422  private:
423  friend class Locker;
424 
426  std::mutex mutex;
428  std::condition_variable cond_var;
429 
433  template <class Container_list>
434  int
435  Wait_and_process_impl(const Container_list &containers,
436  std::chrono::milliseconds timeout,
437  int requests_limit, Predicate ext_predicate);
438  };
439 
441  enum class Type {
443  NONE = 0x0,
445  PROCESSOR = 0x1,
447  COMPLETION_CONTEXT = 0x2,
449  ANY = PROCESSOR | COMPLETION_CONTEXT,
451  TEMPORAL = 0x4,
453  TEMP_COMPLETION_CONTEXT = COMPLETION_CONTEXT | TEMPORAL
454  };
455 
458  const std::string& name,
460 
461  virtual
463 
465  virtual Type
466  Get_type() const
467  {
468  return Type::NONE;
469  }
470 
472  bool
474  {
475  return static_cast<int>(Get_type()) & static_cast<int>(mask);
476  }
477 
483  void
484  Submit_request(Request::Ptr request);
485 
489  void
491  Request::Ptr request,
492  Request_waiter::Locker locker);
493 
499  int
500  Process_requests(int requests_limit = 0);
501 
510  int
511  Process_requests(std::unique_lock<std::mutex> &lock, int requests_limit = 0);
512 
517  void
519 
522  Get_waiter() const
523  {
524  return waiter;
525  }
526 
528  const std::string&
530  {
531  return name;
532  }
533 
538  void
539  Enable();
540 
548  void
549  Disable();
550 
552  bool
553  Is_enabled() const;
554 
555 protected:
563  std::list<Request::Ptr> request_queue;
564 
568  void
569  Processing_loop();
570 
574  virtual void
575  Process_request(Request::Ptr request) = 0;
576 
581  virtual void
582  On_enable();
583 
591  virtual void
592  On_disable();
593 
595  void
596  Set_disabled();
597 
602  virtual void
604 
605 private:
606 
608  void
609  Submit_request_impl(
610  Request::Ptr request,
611  Request_waiter::Locker locker);
612 
614  void
615  Abort_requests();
616 
618  std::atomic_bool is_enabled = { false };
619 
621  std::atomic_bool disable_ongoing = { false };
622 
627  std::atomic_bool abort_ongoing = { false };
628 
630  const std::string name;
631 
633  std::list<Request::Ptr> aborted_request_queue;
634 };
635 
638 
643 public:
650  Locker(Request_waiter::Ptr waiter, bool want_notify = false);
651 
652  ~Locker();
653 
655  Locker(const Locker &) = delete;
656 
658  Locker(Locker &&);
659 
663  void
664  Lock();
665 
669  void
670  Unlock();
671 
673  bool
674  Want_notify() const;
675 
677  bool
678  Is_same_waiter(const Request_waiter::Ptr&) const;
679 
680 private:
682  Request_waiter::Ptr waiter;
684  bool want_notify;
686  bool is_locked;
687 };
688 
691 
692 } /* namespace vsm */
693 } /* namespace ugcs */
694 
695 #endif /* TASK_CONTAINER_H_ */
UGCS root namespace.
Definition: android-linux/ugcs/vsm/platform_sockets.h:27
void Submit_request_locked(Request::Ptr request, Request_waiter::Locker locker)
The same as Submit_request, but with previously acquired lock of the associated waiter.
virtual void Notify()
Notify all listeners about request submission.
bool Is_completion_delivering_started() const
Check if the request completion handler already invoked (but might not be returned yet...
Definition: request_container.h:274
Generic request for implementing inter-threads communications and asynchronous operations.
Definition: request_container.h:37
void Set_disabled()
Disable the container and notify its waiter.
None type used in base class.
std::list< Request::Ptr > request_queue
Queue of pending requests, i.e.
Definition: request_container.h:563
void Disable()
Disable the container.
virtual Type Get_type() const
Get this container type.
Definition: request_container.h:466
Request_waiter::Ptr waiter
Waiter associated with this container.
Definition: request_container.h:559
bool & Timed_out()
Access timed_out member.
Definition: request_container.h:305
virtual void Process_request(Request::Ptr request)=0
Process request.
virtual void On_enable()
Called when the container is enabled.
virtual void On_wait_and_process()
Called when default processing loop want to wait for work and process it.
STL namespace.
Request_container::Request_waiter Request_waiter
Request waiter type for convenient usage.
Definition: request_container.h:637
Callback_base< void >::Ptr<> Handler
Callback denoting a handler of the request.
Definition: request_container.h:85
Callback which can be executed.
Definition: callback.h:86
Locker Lock_notify()
Acquire lock for request submission.
Generic callback which can be used to define and create an instance of an abstract callable operation...
bool Is_request_processing_needed() const
Return true only if the request processing (i.e.
Definition: request_container.h:243
void Unlock()
Unlock the waiter explicitly.
Locker(Request_waiter::Ptr waiter, bool want_notify=false)
Construct locker object.
Request_waiter::Ptr Get_waiter() const
Get request waiter associated with this container.
Definition: request_container.h:522
Various common utilities.
std::shared_ptr< Request > Ptr
Pointer type.
Definition: request_container.h:38
Helper class for RAII-based locking and notifying Request_waiter objects.
Definition: request_container.h:642
Operation completed successfully.
static Ptr Create(Args &&...args)
Create an instance.
Definition: request_container.h:361
void Processing_loop()
Request processing loop implementation.
std::shared_ptr< Request_waiter > Ptr
Pointer type.
Definition: request_container.h:361
Request_container(const std::string &name, Request_waiter::Ptr waiter=Request_waiter::Create())
Create container with default associated waiter.
bool Is_aborted() const
Check if request is aborted.
Definition: request_container.h:251
Pointer class type.
Definition: callback.h:93
int Process_requests(int requests_limit=0)
Process all currently queued requests.
Status
Request processing status which is returned by the handler or set internally.
Definition: request_container.h:43
bool Check_type(Type mask)
Check if the container type conforms the specified characteristic mask.
Definition: request_container.h:473
Status Get_status() const
Get request current status.
Definition: request_container.h:227
bool Is_completion_delivered() const
Check if the request completion notification is delivered.
Definition: request_container.h:265
std::shared_ptr< Request_container > Ptr
Pointer type.
Definition: request_container.h:32
bool Is_done() const
Check if request is fully processed, i.e.
Definition: request_container.h:283
Operation canceled.
Generic container for queued requests.
Definition: request_container.h:31
void Lock()
Lock the waiter explicitly.
Type
Container type.
Definition: request_container.h:441
virtual void On_disable()
Called when the container is terminated.
int Wait_and_process(const std::initializer_list< Request_container::Ptr > &containers, std::chrono::milliseconds timeout=std::chrono::milliseconds::zero(), int requests_limit=0, Predicate predicate=Predicate())
Wait for request submission.
void Set_waiter(Request_waiter::Ptr waiter)
Set request waiter associated with this container.
std::unique_lock< std::mutex > Locker
Smart lock object for request external locking.
Definition: request_container.h:87
bool Is_completed() const
Check if request is completed.
Definition: request_container.h:234
const std::string & Get_name()
Get the name of the container.
Definition: request_container.h:529
bool Want_notify() const
Is locker wants a notify.
bool Is_same_waiter(const Request_waiter::Ptr &) const
Check if locker is bound to this waiter.
void Submit_request(Request::Ptr request)
Submit request to this container for further processing or notification handlers invocation.
bool Is_enabled() const
Check if the container is currently enabled.
bool Is_processing() const
Check if request is still processing.
Definition: request_container.h:258
#define DEFINE_COMMON_CLASS(__class_name,...)
Use this macro to define some common attributes for a class.
Definition: utils.h:25
Request_container::Request Request
Request type for convenient usage.
Definition: request_container.h:690
Locker Lock()
Acquire lock for request getting.
void Enable()
Enable the container.
Represents request synchronization entity which is used for request queues protected access...
Definition: request_container.h:360