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
*
* @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_T.h"
#include "ace/Null_Mutex.h"
#if !defined (ACE_LACKS_PRAGMA_ONCE)
#pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */
#if defined (ACE_HAS_THREADS)
ACE_BEGIN_VERSIONED_NAMESPACE_DECL
/**
* @class ACE_Future_Set
*
* @brief This class implements a mechanism that 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>,
private ACE_Copy_Disabled
{
public:
/// Constructor.
ACE_Future_Set (ACE_Message_Queue<ACE_SYNCH> *future_notification_queue_ = 0);
/// Destructor.
~ACE_Future_Set ();
/**
* 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 () 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 @a tv time to get the @a value. Note that @a tv must be
* specified in absolute time rather than relative time.); get the
* next ACE_Future that is readable. If @a 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:
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.
bool delete_queue_;
};
ACE_END_VERSIONED_NAMESPACE_DECL
#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 */
|