1 //%% (c) Copyright 1993, 1994 Hewlett-Packard Company
2 //%% (c) Copyright 1993, 1994 International Business Machines Corp.
3 //%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
4 //%% (c) Copyright 1993, 1994 Novell, Inc.
5 //%% $TOG: mp_mp.C /main/7 1999/09/21 08:43:02 mgreess $
8 * mp_mp.cc -- Server and client state object for the Message Passer
10 * Copyright (c) 1990,1992 by Sun Microsystems, Inc.
13 #include "mp/mp_global.h"
15 #include "mp/mp_file.h"
16 #include "mp/mp_session.h"
17 #include "mp/mp_c_session.h"
18 #include "mp/mp_procid.h"
19 #include "mp/mp_rpc_client.h"
20 #include "mp/mp_xdr_functions.h"
21 #include "util/tt_base64.h"
22 #include "util/tt_port.h"
23 #include "util/tt_path.h"
24 #include "api/c/api_error.h"
26 #include <sys/resource.h>
28 #include "tt_options.h"
31 /* AIX's FD_ZERO macro uses bzero() without declaring it. */
36 // This file contains methods for the _Tt_mp object which is an object
37 // whose only function is to serve as a placeholder for global
38 // data/objects relevant to the message-passer routines. Another major
39 // use is to hold the various object caches that map object ids to a
40 // single object of the given class.
42 // Really, the _Tt_mp object as we see it here should go away, being
43 // replaced by _Tt_c_mp, which should represent the client's idea
44 // of the ttsession server it's connected to, and _Tt_s_mp, which
45 // represents the global state of a ttsession server.
49 // Global pointer to *the* _Tt_mp object. There should only be one
50 // _Tt_mp object per tooltalk client.
52 _Tt_mp *_tt_mp = (_Tt_mp *)0;
55 // Constructs a _Tt_mp object in the indicated mode.
61 FD_ZERO(&_session_fds);
62 _session_cache = new _Tt_session_table(_tt_session_address);
64 _current_message_id = _current_pattern_id = 0;
65 active_procs = new _Tt_procid_table(_tt_procid_id, 50);
76 // Returns the value of a counter and then increments the counter. Used
77 // to make different messages sent by the same sender unique.
82 return(_current_message_id++);
87 // Returns the value of a counter and then increments the counter. Used
88 // to make different patterns registered by the same sender unique.
93 return(_current_pattern_id++);
100 // Finds the _Tt_file object associated with the network pathname <path>.
101 // Optionally creates the _Tt_file object. Returns:
102 // TT_OK but: if (! createIfNot), then fp.is_null() is possible
107 // TT_ERR_INTERNAL can mean ENOMEM
116 _Tt_string network_path;
117 if (_tt_is_network_path(path)) {
121 network_path = _Tt_db_file::getNetworkPath(path);
124 if (_file_cache.is_null()) {
129 _file_cache = new _Tt_file_table(_Tt_file::networkPath_);
130 if (_file_cache.is_null()) {
136 file = _file_cache->lookup( network_path );
137 if (! file.is_null()) {
142 // If we get to this point, the file is not in the cache
144 Tt_status status = TT_OK;
146 file = new _Tt_file( path );
147 if (file.is_null()) {
150 _Tt_db_results dbStatus = file->getDBResults();
151 status = _tt_get_api_error( dbStatus, _TT_API_FILE );
152 if (status == TT_OK) {
153 _file_cache->insert( file );
154 } else if (status == TT_ERR_INTERNAL) {
155 _tt_syslog( 0, LOG_ERR,
156 "_Tt_db_file::_Tt_db_file(): %d", dbStatus);
162 void _Tt_mp::remove_file(_Tt_string path)
164 _Tt_string network_path = _Tt_db_file::getNetworkPath(path);
165 _file_cache->remove(network_path);
169 remove_session(_Tt_string id)
171 _session_cache->remove(id);
176 // Attempts to find the _Tt_session object associated with the given
177 // session id. If not found and create_ifnot is 1 then a new session is
178 // created and initialized. When it is initialized, the auto_start
179 // parameter is examined. If it is 1 then the new session will be
180 // initialized with the c_init method that will do an auto-start of the
181 // session if it isn't running. Otherwise, the "client_session_init"
182 // method is used which just tries to connect to a running session.
184 // Note that the server does use _Tt_c_session since servers can
185 // act as clients for one another when passing file scoped messages.
188 find_session(_Tt_string id, _Tt_session_ptr &sp,
189 int create_ifnot, int auto_start)
191 Tt_status result = TT_OK;
194 if (_session_cache->lookup(id,s)) {
198 // If this is a session address, try the X session ID
199 // XXX - this is a kludge to deal with X session
200 // IDs now that we use addres_strings as the lookup
201 // key. This should be removed if/when we expunge
202 // our internal use of X session IDs.
203 _Tt_session_table_cursor sc(_session_cache);
206 if (sc->has_id(id)) {
209 // Note: we return right here!
215 if (! create_ifnot || id.len() <= 0) {
216 result = TT_ERR_SESSION;
218 _Tt_c_session_ptr s = new _Tt_c_session();
220 result = s->set_id(id);
221 if (result != TT_OK) return result;
223 if (auto_start) result = s->c_init();
224 if (result != TT_OK) return result;
226 if (result == TT_OK) result = s->client_session_init();
227 if (result != TT_OK) return result;
229 _session_cache->insert(s);
238 save_session_fd(int fd)
240 FD_SET(fd, &_session_fds);
245 find_session_by_fd(int fd, _Tt_session_ptr &sp)
247 _Tt_rpc_client_ptr rpc_client;
248 _Tt_session_table_cursor sc(_session_cache);
251 rpc_client = sc->_rpc_client;
252 if (rpc_client->socket() == fd) {
262 check_if_sessions_alive()
272 s_fds = _session_fds;
273 maxfds = _tt_getdtablesize();
274 n = select(maxfds, (fd_set *) 0, &s_fds, (fd_set *) 0, &tmout);
281 if (FD_ISSET(fd, &s_fds)) {
282 if (! find_session_by_fd(fd, s)) {
283 FD_CLR(fd, &_session_fds);
284 } else if (s->ping() != TT_OK) {
285 id = s->process_tree_id();
286 _tt_mp->remove_session(id);
287 FD_CLR(fd, &_session_fds);