summaryrefslogtreecommitdiff
path: root/ace/Future_Set.h
blob: f776d240177c74dacbbe2682a513167801095b01 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/* -*- C++ -*- */

//=============================================================================
/**
 *  @file    Future_Set.h
 *
 *  $Id$
 *
 *  @author John Tucker <jtucker@infoglide.com>
 */
//=============================================================================

#ifndef ACE_FUTURE_SET_H
#define ACE_FUTURE_SET_H
#include "ace/pre.h"

#include "ace/Thread.h"
#include "ace/Message_Queue.h"
#include "ace/Future.h"
#include "ace/Hash_Map_Manager.h"

#if !defined (ACE_LACKS_PRAGMA_ONCE)
#pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */

#if defined (ACE_HAS_THREADS)

/**
 * @class ACE_Future_Set
 *
 * @brief This class implements a mechanism which allows the values of
 * a collection of <ACE_Future> objects to be accessed by reader threads
 * as they become available.  The caller(s) provide the <ACE_Future_Set> 
 * (i.e. the observer...) with the collection of <ACE_Future> objects 
 * (i.e. the subjects...) that are to be observed using the
 * the <ACE_Future_Set::insert> method.  The caller(s) may then iterate 
 * over the collection in the order in which they become readable using 
 * the <ACE_Future_Set::next_readable> method.
 */
template <class T>
class ACE_Future_Set : public ACE_Future_Observer<T>
{
public:
  // = Initialization and termination methods.

  /// Constructor.
  ACE_Future_Set (ACE_Message_Queue<ACE_SYNCH> *future_notification_queue_ = 0);

  /// Destructor.
  ~ACE_Future_Set (void);

  /// Return 1 if their are no <ACE_Future> objects left on its queue and
  /// 0 otherwise
  ///
  /// When an <ACE_Future_Set> has no <ACE_Future> subjects to observe it is
  /// empty. The <ACE_Future_Set> is in the empty state when either the caller(s)
  /// have retrieved every readable <ACE_Future> subject assigned the 
  /// <ACE_Future_Set> via the <ACE_Future_Set::next_readable> method,
  /// or when the <ACE_Future_Set> has not been assigned any subjects.
  int is_empty (void) const;

  /**
   * Enqueus the given <ACE_Future> into this objects queue when it is
   * readable.
   *
   * Returns 0 if the future is successfully inserted, 1 if the
   * future is already inserted, and -1 if failures occur.
   */
  int insert (ACE_Future<T> &future);

  /**
   * Wait up to <tv> time to get the <value>.  Note that <tv> must be
   * specified in absolute time rather than relative time.); get the
   * next <ACE_Future> that is readable.  If <tv> = 0, the will block
   * forever.
   *
   * If a readable future becomes available, then the input 
   * <ACE_Future> object param will be assigned with it and 1 will 
   * be returned.  If the <ACE_Future_Set> is empty (i.e. see definition
   * of <ACE_Future_Set::is_empty>), then 0 is returned.
   *
   * When a readable <ACE_Future> object is retrieved via the 
   * <ACE_Future_Set::next_readable> method, the <ACE_Future_Set> will
   * remove that <ACE_Future> object from its list of subjects.
   */
  int next_readable (ACE_Future<T> &result,
                     ACE_Time_Value *tv = 0);

  /// Called by the <ACE_Future> subject in which we are subscribed to
  /// when its value is written to.
  virtual void update (const ACE_Future<T> &future);

  /// Declare the dynamic allocation hooks.
  ACE_ALLOC_HOOK_DECLARE;

private:
  // = Disallow these operations.
  ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Future_Set<T> &))
  ACE_UNIMPLEMENTED_FUNC (ACE_Future_Set (const ACE_Future_Set<T> &))

  typedef ACE_Future<T> FUTURE;

  typedef ACE_Future_Rep<T> FUTURE_REP;

  typedef ACE_Future_Holder<T> FUTURE_HOLDER;

  typedef ACE_Pointer_Hash<FUTURE_REP *> FUTURE_REP_HASH;

  typedef ACE_Equal_To<FUTURE_REP *> FUTURE_REP_COMPARE;

  typedef ACE_Hash_Map_Manager_Ex<FUTURE_REP *,
                                  FUTURE_HOLDER *,
                                  FUTURE_REP_HASH,
                                  FUTURE_REP_COMPARE,
			          ACE_Null_Mutex> FUTURE_HASH_MAP;

  /// Map of <ACE_Futures>, subjects, which have not been written to by
  /// client's writer thread.
  FUTURE_HASH_MAP future_map_;

  /// Message queue for notifying the reader thread of <ACE_Futures> which
  /// have been written to by client's writer thread.
  ACE_Message_Queue<ACE_SYNCH> *future_notification_queue_;

  /// Keeps track of whether we need to delete the message queue.
  int delete_queue_;
};

#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
#include "ace/Future_Set.cpp"
#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */

#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
#pragma implementation ("Future_Set.cpp")
#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */

#endif /* ACE_HAS_THREADS */
#include "ace/post.h"
#endif /* ACE_FUTURE_SET_H */