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
140
141
142
143
|
// @(#)connmgr.hh 1.2 95/09/24
// Copyright 1994-1995 by Sun Microsystems Inc.
// All Rights Reserved
//
// Simple threaded asymmetric TCP connection manager.
//
#ifndef _CONNMGR_HH
#define _CONNMGR_HH
#include <ace/OS.h>
#if unix
# include <sys/time.h>
#else // __WIN32__
# include <winsock.h>
#endif
#ifdef DEBUG
#include <stdio.h>
#endif
//
// Utility class that may not really belong here; it's currently used only
// with connection endpoints though.
//
// THREADING NOTE: note that the pointer doesn't change, so two threads
// could share an "autorelease<T>" value if they collaborated about safe
// refcounting and destruction.
//
template <class T>
class autorelease {
public:
autorelease &operator = (T *ptr)
{
if (_state) _state->release();
_state = ptr; return *this;
}
operator int () { return _state ? 1 : 0; }
T *operator -> () { return _state; }
autorelease () { _state = 0; }
~autorelease ()
{ if (_state) _state->release (); }
private:
T *_state;
};
//
// Client endpoints are acquired just by looking them up; they're created
// if needed, and may be closed when they're not in use.
//
// NOTE: timeout on lookup/create would be a nice quality-of-service
// knob to be able to tweak...
//
struct client_endpoint {
ACE_HANDLE fd;
static client_endpoint *lookup (
char *host,
unsigned short port,
CORBA_Environment &env
);
void release ();
#ifdef DEBUG
static void dump (FILE *);
#endif
private:
char *hostname;
unsigned short port;
unsigned refcount;
client_endpoint *next;
#ifdef __GNUG__
//
// G++ (even 2.6.3) stupidly thinks instances can't be
// created This de-warns.
//
friend class everyone_needs_a_friend;
#endif
};
//
// Server endpoints start out by waiting passively for input on a port.
// New connections may be created. Old ones may be disconnected.
//
// NOTE: this version doesn't bind to specific host addresses on
// multihomed hosts, so it's not yet suitable for use on firewalls.
//
// NOTE: this version also doesn't listen on more than one port at a time.
//
class server_endpoint {
public:
ACE_HANDLE fd;
static server_endpoint *initialize (
unsigned short &port,
// XXX char *ifname,
CORBA_Environment &env
);
server_endpoint *block_for_connection (
CORBA_Boolean eager,
timeval *timeout,
CORBA_Environment &env
);
void shutdown_connections (
// add a flag saying some, all?
void (*close_conn)(
ACE_HANDLE &fd,
void *info
),
void *info
);
void release ();
#ifdef DEBUG
static void dump (FILE *);
#endif
private:
unsigned short port;
CORBA_Boolean is_passive;
unsigned refcount;
server_endpoint *next;
#if defined (__GNUG__)
//
// G++ (even 2.6.3) stupidly thinks instances can't be
// created. This de-warns.
//
friend class everyone_needs_a_friend;
#endif
};
#endif // _CONNMGR_HH
|