summaryrefslogtreecommitdiff
path: root/TAO/IIOP/lib/connmgr.hh
blob: fd90b04a69cce347469af2e0e1f295804c7e45eb (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
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