libs-base/Source/Connection.m

1457 lines
38 KiB
Mathematica
Raw Normal View History

/* Implementation of connection object for remote object messaging
Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: R. Andrew McCallum <mccallum@gnu.ai.mit.edu>
Date: July 1994
This file is part of the GNU Objective C Class Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* To do:
Integrate with NSRunLoop
Pass exceptions back to client.
Find bug with proxies of invalidated connections.
Make it thread-safe.
Support @"*" hostname.
*/
/* RMC == Remote Method Coder, or Remote Method Call.
It's an instance of ConnectedEncoder or ConnectedDecoder. */
#include <objects/stdobjects.h>
#include <objects/Connection.h>
#include <objects/Proxy.h>
#include <objects/ConnectedCoder.h>
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
#include <objects/TcpPort.h>
#include <objects/Array.h>
#include <objects/Dictionary.h>
#include <objects/Queue.h>
#include <objects/mframe.h>
#include <objects/Notification.h>
#include <objects/RunLoop.h>
#include <objects/MallocAddress.h>
#include <Foundation/NSString.h>
#include <Foundation/NSDate.h>
#include <Foundation/NSException.h>
#include <assert.h>
@interface Connection (GettingCoderInterface)
- (void) _handleRmc: rmc;
- (void) _handleQueuedRmcRequests;
- _getReceivedReplyRmcWithSequenceNumber: (int)n;
- newSendingRequestRmc;
- newSendingReplyRmcWithSequenceNumber: (int)n;
- (int) _newMsgNumber;
@end
@interface Connection (Private)
- _superInit;
@end
#define proxiesHashGate refGate
#define sequenceNumberGate refGate
/* xxx Fix this! */
#define refGate nil
static inline BOOL
class_is_kind_of (Class self, Class aClassObject)
{
Class class;
for (class = self; class!=Nil; class = class_get_super_class(class))
if (class==aClassObject)
return YES;
return NO;
}
static inline unsigned int
hash_int (cache_ptr cache, const void *key)
{
return (unsigned)key & cache->mask;
}
static inline int
compare_ints (const void *k1, const void *k2)
{
return !(k1 - k2);
}
static int
type_get_number_of_arguments (const char *type)
{
int i = 0;
while (*type)
{
type = objc_skip_argspec (type);
i += 1;
}
return i - 1;
}
/* class defaults */
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
static id default_in_port_class;
static id default_out_port_class;
static id default_proxy_class;
static id default_encoding_class;
static id default_decoding_class;
static int default_in_timeout;
static int default_out_timeout;
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
static int debug_connection = 1;
/* Perhaps this should be a hashtable, keyed by remote port.
But we may also need to include the local port---even though
when receiving the local port is fixed, there may be more than
one registered connection (with different in ports) in the
application. */
/* We could write -hash and -isEqual implementations for Connection */
static Array *connection_array;
static Lock *connection_array_gate;
static Dictionary *root_object_dictionary;
static Lock *root_object_dictionary_gate;
static NSMapTable *in_port_2_ancestor;
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
static NSMapTable *all_connections_local_targets = NULL;
/* rmc handling */
static Queue *received_request_rmc_queue;
static Lock *received_request_rmc_queue_gate;
static Queue *received_reply_rmc_queue;
static Lock *received_reply_rmc_queue_gate;
static int messages_received_count;
@implementation Connection
+ (void) initialize
{
connection_array = [[Array alloc] init];
connection_array_gate = [Lock new];
/* xxx When NSHashTable's are working, change this. */
all_connections_local_targets =
NSCreateMapTable (NSNonOwnedPointerMapKeyCallBacks,
NSNonOwnedPointerMapValueCallBacks, 0);
received_request_rmc_queue = [[Queue alloc] init];
received_request_rmc_queue_gate = [Lock new];
received_reply_rmc_queue = [[Queue alloc] init];
received_reply_rmc_queue_gate = [Lock new];
root_object_dictionary = [[Dictionary alloc] init];
root_object_dictionary_gate = [Lock new];
in_port_2_ancestor =
NSCreateMapTable (NSNonOwnedPointerMapKeyCallBacks,
NSNonOwnedPointerMapValueCallBacks, 0);
messages_received_count = 0;
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
default_in_port_class = [TcpInPort class];
default_out_port_class = [TcpOutPort class];
default_proxy_class = [Proxy class];
default_encoding_class = [ConnectedEncoder class];
default_decoding_class = [ConnectedDecoder class];
default_in_timeout = CONNECTION_DEFAULT_TIMEOUT;
default_out_timeout = CONNECTION_DEFAULT_TIMEOUT;
}
/* Getting and setting class variables */
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
+ (void) setDefaultInPortClass: (Class)aClass
{
default_in_port_class = aClass;
}
+ (Class) defaultInPortClass
{
return default_in_port_class;
}
+ (void) setDefaultOutPortClass: (Class)aClass
{
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
default_out_port_class = aClass;
}
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
+ (Class) defaultOutPortClass
{
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
return default_out_port_class;
}
+ (void) setDefaultProxyClass: (Class)aClass
{
default_proxy_class = aClass;
}
+ (Class) defaultProxyClass
{
return default_proxy_class;
}
+ (void) setDefaultDecodingClass: (Class) aClass
{
default_decoding_class = aClass;
}
+ (Class) default_decoding_class
{
return default_decoding_class;
}
+ (int) defaultOutTimeout
{
return default_out_timeout;
}
+ (void) setDefaultOutTimeout: (int)to
{
default_out_timeout = to;
}
+ (int) defaultInTimeout
{
return default_in_timeout;
}
+ (void) setDefaultInTimeout: (int)to
{
default_in_timeout = to;
}
/* Class-wide stats and collections. */
+ (int) messagesReceived
{
return messages_received_count;
}
+ (id <Collecting>) allConnections
{
return [connection_array copy];
}
+ (unsigned) connectionsCount
{
return [connection_array count];
}
+ (unsigned) connectionsCountWithInPort: (InPort*)aPort
{
unsigned count = 0;
id o;
[connection_array_gate lock];
FOR_ARRAY (connection_array, o)
{
if ([aPort isEqual: [o inPort]])
count++;
}
END_FOR_ARRAY (connection_array);
[connection_array_gate unlock];
return count;
}
/* Creating and initializing connections. */
- init
{
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
id newPort = [default_in_port_class newForReceiving];
id newConn =
[Connection newForInPort:newPort outPort:nil ancestorConnection:nil];
[self release];
return newConn;
}
+ new
{
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
id newPort = [default_in_port_class newForReceiving];
id newConn =
[Connection newForInPort:newPort outPort:nil ancestorConnection:nil];
return newConn;
}
+ (Connection*) newWithRootObject: anObj;
{
id newPort;
id newConn;
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
newPort = [default_in_port_class newForReceiving];
newConn = [self newForInPort:newPort outPort:nil
ancestorConnection:nil];
[self setRootObject:anObj forInPort:newPort];
return newConn;
}
/* I want this method name to clearly indicate that we're not connecting
to a pre-existing registration name, we're registering a new name,
and this method will fail if that name has already been registered.
This is why I don't like "newWithRegisteredName:" --- it's unclear
if we're connecting to another Connection that already registered
with that name. */
+ (Connection*) newRegisteringAtName: (id <String>)n withRootObject: anObj
{
id newPort;
id newConn;
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
newPort = [default_in_port_class newForReceivingFromRegisteredName: n];
newConn = [self newForInPort:newPort outPort:nil
ancestorConnection:nil];
[self setRootObject:anObj forInPort:newPort];
return newConn;
}
+ (Proxy*) rootProxyAtName: (id <String>)n
{
return [self rootProxyAtName: n onHost: @""];
}
+ (Proxy*) rootProxyAtName: (id <String>)n onHost: (id <String>)h
{
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
id p = [default_out_port_class newForSendingToRegisteredName: n onHost: h];
return [self rootProxyAtPort: p];
}
+ (Proxy*) rootProxyAtPort: (OutPort*)anOutPort
{
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
id newInPort = [default_in_port_class newForReceiving];
return [self rootProxyAtPort: anOutPort withInPort: newInPort];
}
+ (Proxy*) rootProxyAtPort: (OutPort*)anOutPort withInPort: (InPort*)anInPort
{
Connection *newConn = [self newForInPort:anInPort
outPort:anOutPort
ancestorConnection:nil];
Proxy *newRemote;
newRemote = [newConn rootProxy];
return newRemote;
}
/* This is the designated initializer for Connection */
+ (Connection*) newForInPort: (InPort*)ip outPort: (OutPort*)op
ancestorConnection: ancestor
{
Connection *newConn;
int i, count;
id newConnInPort, newConnOutPort;
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
NSParameterAssert (ip);
[connection_array_gate lock];
/* Find previously existing connection if there */
/* xxx Clean this up */
count = [connection_array count];
for (i = 0; i < count; i++)
{
newConn = [connection_array objectAtIndex: i];
newConnInPort = [newConn inPort];
newConnOutPort = [newConn outPort];
if ([newConnInPort isEqual: ip]
&& [newConnOutPort isEqual: op])
{
[connection_array_gate unlock];
return newConn;
}
}
newConn = [[Connection alloc] _superInit];
if (debug_connection)
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
fprintf(stderr, "Created new connection 0x%x\n\t%s\n\t%s\n",
(unsigned)newConn,
[[ip description] cStringNoCopy],
[[op description] cStringNoCopy]);
newConn->is_valid = 1;
newConn->in_port = ip;
[ip retain];
newConn->out_port = op;
[op retain];
newConn->message_count = 0;
/* This maps (void*)obj to (id)obj. The obj's are retained.
We use this instead of an NSHashTable because we only care about
the object's address, and don't want to send the -hash message to it. */
newConn->local_targets =
NSCreateMapTable (NSNonOwnedPointerMapKeyCallBacks,
NSObjectMapValueCallBacks, 0);
/* This maps [proxy targetForProxy] to proxy. The proxy's are retained. */
newConn->remote_proxies =
NSCreateMapTable (NSIntMapKeyCallBacks,
NSObjectMapValueCallBacks, 0);
newConn->incoming_xref_2_const_ptr =
NSCreateMapTable (NSIntMapKeyCallBacks,
NSNonOwnedPointerMapValueCallBacks, 0);
newConn->outgoing_const_ptr_2_xref =
NSCreateMapTable (NSIntMapKeyCallBacks,
NSNonOwnedPointerMapValueCallBacks, 0);
newConn->in_timeout = [self defaultInTimeout];
newConn->out_timeout = [self defaultOutTimeout];
newConn->encoding_class = default_encoding_class;
/* xxx ANCESTOR argument is currently ignored; in the future it
will be removed. */
/* xxx It this the correct behavior? */
if (!(ancestor = NSMapGet (in_port_2_ancestor, ip)))
{
NSMapInsert (in_port_2_ancestor, ip, newConn);
[[RunLoop currentInstance] addPort: ip
forMode: RunLoopDefaultMode];
[[RunLoop currentInstance] addPort: ip
forMode: RunLoopConnectionReplyMode];
/* This will cause the connection with the registered name
to receive the -invokeWithObject: from the IN_PORT.
This ends up being the ancestor of future new Connections
on this in port. */
/* xxx Could it happen that this connection was invalidated, but
the others would still be OK? That would cause problems.
No. I don't think that can happen. */
[ip setReceivedPacketInvocation: (id)[self class]];
}
if (ancestor)
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
{
newConn->in_port_class = [ancestor inPortClass];
newConn->out_port_class = [ancestor outPortClass];
}
else
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
{
newConn->in_port_class = default_in_port_class;
newConn->out_port_class = default_out_port_class;
}
newConn->delay_dialog_interruptions = YES;
newConn->reply_depth = 0;
newConn->delegate = nil;
/* Here ask the delegate for permission. */
/* delegate is responsible for freeing newConn if it returns something
different. */
if ([[ancestor delegate] respondsTo:@selector(connection:didConnect:)])
newConn = [[ancestor delegate] connection:ancestor
didConnect:newConn];
/* Register outselves for invalidation notification when the
ports become invalid. */
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
[NotificationDispatcher addObserver: newConn
selector: @selector(portIsInvalid:)
name: PortBecameInvalidNotification
object: ip];
if (op)
[NotificationDispatcher addObserver: newConn
selector: @selector(portIsInvalid:)
name: PortBecameInvalidNotification
object: op];
/* if OP is nil, making this notification request would have
registered us to receive all PortBecameInvalidNotification
requests, independent of which port posted them. This isn't
what we want. */
/* xxx This is weird, though. When will newConn ever get dealloc'ed?
connectionArray will retain it, but connectionArray will never get
deallocated. This sort of retain/release cirularity must be common
enough. Think about this and fix it. */
[connection_array addObject: newConn];
[connection_array_gate unlock];
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
[NotificationDispatcher
postNotificationName: ConnectionWasCreatedNotification
object: newConn];
return newConn;
}
- _superInit
{
[super init];
return self;
}
/* Creating new rmc's for encoding requests and replies */
/* Create a new, empty rmc, which will be filled with a request. */
- newSendingRequestRmc
{
id rmc;
NSParameterAssert(in_port);
NSParameterAssert (is_valid);
rmc = [[self encodingClass] newForWritingWithConnection: self
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
sequenceNumber: [self _newMsgNumber]
identifier: METHOD_REQUEST];
return rmc;
}
/* Create a new, empty rmc, which will be filled with a reply to msg #n. */
- newSendingReplyRmcWithSequenceNumber: (int)n
{
id rmc = [[self encodingClass] newForWritingWithConnection: self
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
sequenceNumber: n
identifier: METHOD_REPLY];
NSParameterAssert (is_valid);
return rmc;
}
/* Methods for handling client and server, requests and replies */
/* Proxy's -forward:: method calls this to the the message over the wire. */
- (retval_t) forwardForProxy: (Proxy*)object
selector: (SEL)sel
argFrame: (arglist_t)argframe
{
ConnectedEncoder *op;
/* The callback for encoding the args of the method call. */
void encoder (int argnum, void *datum, const char *type, int flags)
{
#define ENCODED_ARGNAME @"argument value"
switch (*type)
{
case _C_ID:
if (flags & _F_BYCOPY)
[op encodeBycopyObject: *(id*)datum withName: ENCODED_ARGNAME];
else
[op encodeObject: *(id*)datum withName: ENCODED_ARGNAME];
break;
default:
[op encodeValueOfObjCType: type at: datum withName: ENCODED_ARGNAME];
}
}
/* Encode the method on an RMC, and send it. */
{
BOOL out_parameters;
const char *type;
retval_t retframe;
int seq_num;
NSParameterAssert (is_valid);
op = [self newSendingRequestRmc];
seq_num = [op sequenceNumber];
/* get the method types from the selector */
#if NeXT_runtime
[NSException
raise: NSGenericException
format: @"Sorry, distributed objects does not work with NeXT runtime"];
/* type = [object selectorTypeForProxy:sel]; */
#else
type = sel_get_type(sel);
#endif
NSParameterAssert(type);
NSParameterAssert(*type);
/* Send the types that we're using, so that the performer knows
exactly what qualifiers we're using.
If all selectors included qualifiers, and if I could make
sel_types_match() work the way I wanted, we wouldn't need to do
this. */
[op encodeValueOfCType: @encode(char*)
at: &type
withName: @"selector type"];
/* xxx This doesn't work with proxies and the NeXT runtime because
type may be a method_type from a remote machine with a
different architecture, and its argframe layout specifiers
won't be right for this machine! */
out_parameters = mframe_dissect_call (argframe, type, encoder);
/* Send the rmc */
[op dismiss];
/* Get the reply rmc, and decode it. */
{
ConnectedDecoder *ip = nil;
int last_argnum;
BOOL is_exception;
void decoder(int argnum, void *datum, const char *type, int flags)
{
NSParameterAssert(ip != (id)-1);
/* If we didn't get the reply packet yet, get it now. */
if (!ip)
{
/* xxx Why do we get the reply packet in here, and not
just before calling dissect_method_return() below? */
ip = [self _getReceivedReplyRmcWithSequenceNumber:seq_num];
/* Find out if the server is returning an exception instead
of the return values. */
[ip decodeValueOfCType: @encode(BOOL)
at: &is_exception
withName: NULL];
if (is_exception)
{
/* Decode the exception object, and raise it. */
id exc;
[ip decodeObjectAt: &exc
withName: NULL];
[ip dismiss];
/* xxx Is there anything else to clean up in
dissect_method_return()? */
[exc raise];
}
}
[ip decodeValueOfObjCType: type at: datum withName: NULL];
/* -decodeValueOfCType:at:withName: malloc's new memory
for char*'s. We need to make sure it gets freed eventually
so we don't have a memory leak. Request here that it be
autorelease'ed. */
if (*type == _C_CHARPTR)
[MallocAddress autoreleaseMallocAddress: *(char**)datum];
if (argnum == last_argnum)
{
/* this must be here to avoid trashing alloca'ed retframe */
[ip dismiss];
ip = (id)-1;
}
}
last_argnum = type_get_number_of_arguments(type) - 1;
retframe = mframe_build_return (argframe, type, out_parameters,
decoder);
return retframe;
}
}
}
/* Connection calls this to service the incoming method request. */
- (void) _service_forwardForProxy: aRmc
{
char *forward_type;
id op = nil;
int reply_sequence_number;
int numargs;
void decoder (int argnum, void *datum, const char *type)
{
[aRmc decodeValueOfObjCType:type
at:datum
withName:NULL];
/* -decodeValueOfCType:at:withName: malloc's new memory
for char*'s. We need to make sure it gets freed eventually
so we don't have a memory leak. Request here that it be
autorelease'ed. */
if (*type == _C_CHARPTR)
[MallocAddress autoreleaseMallocAddress: *(char**)datum];
/* We need this "dismiss" to happen here and not later so that Coder
"-awake..." methods will get sent before the __builtin_apply! */
if (argnum == numargs-1)
[aRmc dismiss];
}
void encoder (int argnum, void *datum, const char *type, int flags)
{
#define ENCODED_RETNAME @"return value"
if (op == nil)
{
BOOL is_exception = NO;
op = [self newSendingReplyRmcWithSequenceNumber:
reply_sequence_number];
[op encodeValueOfCType: @encode(BOOL)
at: &is_exception
withName: @"Exceptional reply flag"];
}
switch (*type)
{
case _C_ID:
if (flags & _F_BYCOPY)
[op encodeBycopyObject:*(id*)datum withName:ENCODED_RETNAME];
else
[op encodeObject:*(id*)datum withName:ENCODED_RETNAME];
break;
default:
[op encodeValueOfObjCType:type at:datum withName:ENCODED_RETNAME];
}
}
/* Make sure don't let exceptions caused by servicing the client's
request cause us to crash. */
NS_DURING
{
NSParameterAssert (is_valid);
/* Save this for later */
reply_sequence_number = [aRmc sequenceNumber];
/* Get the types that we're using, so that we know
exactly what qualifiers the forwarder used.
If all selectors included qualifiers and I could make
sel_types_match() work the way I wanted, we wouldn't need
to do this. */
[aRmc decodeValueOfCType:@encode(char*)
at:&forward_type
withName:NULL];
numargs = type_get_number_of_arguments(forward_type);
mframe_do_call (forward_type, decoder, encoder);
[op dismiss];
}
/* Make sure we pass all exceptions back to the requestor. */
NS_HANDLER
{
BOOL is_exception = YES;
/* Try to clean up a little. */
if (op)
[op release];
/* Send the exception back to the client. */
op = [self newSendingReplyRmcWithSequenceNumber: reply_sequence_number];
[op encodeValueOfCType: @encode(BOOL)
at: &is_exception
withName: @"Exceptional reply flag"];
[op encodeBycopyObject: exception
withName: @"Exception object"];
[op dismiss];
}
NS_ENDHANDLER;
if (forward_type)
(*objc_free) (forward_type);
}
- (Proxy*) rootProxy
{
id op, ip;
Proxy *newProxy;
int seq_num = [self _newMsgNumber];
NSParameterAssert(in_port);
NSParameterAssert (is_valid);
op = [[self encodingClass]
newForWritingWithConnection: self
sequenceNumber: seq_num
identifier: ROOTPROXY_REQUEST];
[op dismiss];
ip = [self _getReceivedReplyRmcWithSequenceNumber: seq_num];
[ip decodeObjectAt: &newProxy withName: NULL];
NSParameterAssert (class_is_kind_of (newProxy->isa, objc_get_class ("Proxy")));
[ip dismiss];
return newProxy;
}
- (void) _service_rootObject: rmc
{
id rootObject = [Connection rootObjectForInPort:in_port];
ConnectedEncoder* op = [[self encodingClass]
newForWritingWithConnection: [rmc connection]
sequenceNumber: [rmc sequenceNumber]
identifier: ROOTPROXY_REPLY];
NSParameterAssert (in_port);
NSParameterAssert (is_valid);
/* Perhaps we should turn this into a class method. */
NSParameterAssert([rmc connection] == self);
[op encodeObject: rootObject withName: @"root object"];
[op dismiss];
}
- (void) shutdown
{
id op;
NSParameterAssert(in_port);
NSParameterAssert (is_valid);
op = [[self encodingClass]
newForWritingWithConnection: self
sequenceNumber: [self _newMsgNumber]
identifier: CONNECTION_SHUTDOWN];
[op dismiss];
}
- (void) _service_shutdown: rmc forConnection: receiving_connection
{
NSParameterAssert (is_valid);
[self invalidate];
if (receiving_connection == self)
[NSException raise: NSGenericException
format: @"connection waiting for request was shut down"];
[self dealloc]; // xxx release instead? YES!!
[rmc dismiss];
}
- (const char *) typeForSelector: (SEL)sel remoteTarget: (unsigned)target
{
id op, ip;
char *type;
int seq_num;
NSParameterAssert(in_port);
NSParameterAssert (is_valid);
seq_num = [self _newMsgNumber];
op = [[self encodingClass]
newForWritingWithConnection: self
sequenceNumber: seq_num
identifier: METHODTYPE_REQUEST];
[op encodeValueOfObjCType:":"
at:&sel
withName:NULL];
[op encodeValueOfCType:@encode(unsigned)
at:&target
withName:NULL];
[op dismiss];
ip = [self _getReceivedReplyRmcWithSequenceNumber:seq_num];
[ip decodeValueOfCType:@encode(char*)
at:&type
withName:NULL];
[ip dismiss];
return type;
}
- (void) _service_typeForSelector: rmc
{
ConnectedEncoder* op;
unsigned target;
SEL sel;
const char *type;
struct objc_method* m;
NSParameterAssert(in_port);
NSParameterAssert (is_valid);
NSParameterAssert([rmc connection] == self);
op = [[self encodingClass]
newForWritingWithConnection: [rmc connection]
sequenceNumber: [rmc sequenceNumber]
identifier: METHODTYPE_REPLY];
[rmc decodeValueOfObjCType:":"
at:&sel
withName:NULL];
[rmc decodeValueOfCType:@encode(unsigned)
at:&target
withName:NULL];
/* xxx We should make sure that TARGET is a valid object. */
/* Not actually a Proxy, but we avoid the warnings "id" would have made. */
m = class_get_instance_method(((Proxy*)target)->isa, sel);
/* Perhaps I need to be more careful in the line above to get the
version of the method types that has the type qualifiers in it.
Search the protocols list. */
if (m)
type = m->method_types;
else
type = "";
[op encodeValueOfCType:@encode(char*)
at:&type
withName:@"Requested Method Type for Target"];
[op dismiss];
}
/* Running the connection, getting/sending requests/replies. */
- (void) runConnectionUntilDate: date
{
[RunLoop runUntilDate: date];
}
- (void) runConnection
{
[self runConnectionUntilDate: [NSDate distantFuture]];
}
- (void) _handleRmc: rmc
{
switch ([rmc identifier])
{
case ROOTPROXY_REQUEST:
/* It won't take much time to handle this, so go ahead and service
it, even if we are waiting for a reply. */
[[rmc connection] _service_rootObject: rmc];
[rmc dismiss];
break;
case METHODTYPE_REQUEST:
/* It won't take much time to handle this, so go ahead and service
it, even if we are waiting for a reply. */
[[rmc connection] _service_typeForSelector: rmc];
[rmc dismiss];
break;
case METHOD_REQUEST:
/* We just got a new request; we need to decide whether to queue
it or service it now.
If the REPLY_DEPTH is 0, then we aren't in the middle of waiting
for a reply, we are waiting for requests---so service it now.
If REPLY_DEPTH is non-zero, we may still want to service it now
if it is a request made as a callback from our peer---the request
is part of the remote code necessary to finish calculating our
reply; we know it's a callback from our peer if the [RMC CONNECTION]
is self.
If REPLY_DEPTH is non-zero, and the [RMC CONNECTION] is not self,
then we may still want to service it now if DELAY_DIALOG_INTERRUPTIONS
is false. */
if (reply_depth == 0
|| [rmc connection] == self
|| !delay_dialog_interruptions)
{
[[rmc connection] _service_forwardForProxy: rmc];
/* Service any requests that were queued while we
were waiting for replies.
xxx Is this the right place for this check? */
if (reply_depth == 0)
[self _handleQueuedRmcRequests];
}
else
{
[received_request_rmc_queue_gate lock];
[received_request_rmc_queue enqueueObject: rmc];
[received_request_rmc_queue_gate unlock];
}
break;
case ROOTPROXY_REPLY:
case METHOD_REPLY:
case METHODTYPE_REPLY:
/* Remember multi-threaded callbacks will have to be handled specially */
[received_reply_rmc_queue_gate lock];
[received_reply_rmc_queue enqueueObject: rmc];
[received_reply_rmc_queue_gate unlock];
break;
case CONNECTION_SHUTDOWN:
{
[[rmc connection] _service_shutdown: rmc forConnection: self];
break;
}
default:
[NSException raise: NSGenericException
format: @"unrecognized ConnectedDecoder identifier"];
}
}
- (void) _handleQueuedRmcRequests
{
id rmc;
[received_request_rmc_queue_gate lock];
while ((rmc = [received_request_rmc_queue dequeueObject]))
{
[received_request_rmc_queue_gate unlock];
[self _handleRmc: rmc];
[received_request_rmc_queue_gate lock];
}
[received_request_rmc_queue_gate unlock];
}
/* Deal with an RMC, either by queuing it for later service, or
by servicing it right away. This method is called by the
in_port's received-packet-invocation. */
/* Look for it on the queue, if it is not there, return nil. */
- _getReceivedReplyRmcFromQueueWithSequenceNumber: (int)sn
{
id the_rmc = nil;
unsigned count, i;
[received_reply_rmc_queue_gate lock];
count = [received_reply_rmc_queue count];
/* xxx There should be a per-thread queue of rmcs so we can do
callbacks when multi-threaded. */
for (i = 0; i < count; i++)
{
id a_rmc = [received_reply_rmc_queue objectAtIndex: i];
if ([a_rmc connection] == self
&& [a_rmc sequenceNumber] == sn)
{
if (debug_connection)
printf("Getting received reply from queue\n");
[received_reply_rmc_queue removeObjectAtIndex: i];
the_rmc = a_rmc;
break;
}
/* xxx Make sure that there isn't a higher sequenceNumber, meaning
that we somehow dropped a packet. */
}
[received_reply_rmc_queue_gate unlock];
return the_rmc;
}
/* Check the queue, then try to get it from the network by waiting
while we run the RunLoop. Return nil if we don't get anything
before timing out. */
- _getReceivedReplyRmcWithSequenceNumber: (int)sn
{
id rmc;
id timeout_date = nil;
reply_depth++;
while (!(rmc = [self _getReceivedReplyRmcFromQueueWithSequenceNumber: sn]))
{
if (!timeout_date)
timeout_date = [[NSDate alloc]
initWithTimeIntervalSinceNow: in_timeout];
[RunLoop runOnceBeforeDate: timeout_date
forMode: RunLoopConnectionReplyMode];
}
reply_depth--;
return rmc;
}
/* Sneaky, sneaky. See "sneaky" comment in TcpPort.m.
This method is called by InPort when it receives a new packet. */
+ (void) invokeWithObject: packet
{
id rmc = [ConnectedDecoder
newDecodingWithPacket: packet
connection: NSMapGet (in_port_2_ancestor,
[packet receivingInPort])];
[[rmc connection] _handleRmc: rmc];
}
- (int) _newMsgNumber
{
int n;
NSParameterAssert (is_valid);
[sequenceNumberGate lock];
n = message_count++;
[sequenceNumberGate unlock];
return n;
}
/* Managing objects and proxies. */
- (void) addLocalObject: anObj
{
NSParameterAssert (is_valid);
[proxiesHashGate lock];
/* xxx Do we need to check to make sure it's not already there? */
/* This retains anObj. */
NSMapInsert (local_targets, (void*)anObj, anObj);
/* This does not retain anObj. */
NSMapInsert (all_connections_local_targets, (void*)anObj, anObj);
[proxiesHashGate unlock];
}
/* This should get called whenever an object free's itself */
+ (void) removeLocalObject: anObj
{
id c;
int i, count = [connection_array count];
/* Don't assert (is_valid); */
for (i = 0; i < count; i++)
{
c = [connection_array objectAtIndex:i];
[c removeLocalObject: anObj];
[c removeProxy: anObj];
}
}
- (void) removeLocalObject: anObj
{
/* Don't assert (is_valid); */
[proxiesHashGate lock];
/* This also releases anObj */
NSMapRemove (local_targets, (void*)anObj);
NSMapRemove (all_connections_local_targets, (void*)anObj);
[proxiesHashGate unlock];
}
- (void) removeProxy: (Proxy*)aProxy
{
unsigned target = [aProxy targetForProxy];
/* Don't assert (is_valid); */
[proxiesHashGate lock];
/* This also releases aProxy */
NSMapRemove (remote_proxies, (void*)target);
[proxiesHashGate unlock];
}
- (id <Collecting>) localObjects
{
id c;
/* Don't assert (is_valid); */
[proxiesHashGate lock];
c = NSAllMapTableValues (local_targets);
[proxiesHashGate unlock];
return c;
}
- (id <Collecting>) proxies
{
id c;
/* Don't assert (is_valid); */
[proxiesHashGate lock];
c = NSAllMapTableValues (remote_proxies);
[proxiesHashGate unlock];
return c;
}
- (Proxy*) proxyForTarget: (unsigned)target
{
Proxy *p;
/* Don't assert (is_valid); */
[proxiesHashGate lock];
p = NSMapGet (remote_proxies, (void*)target);
[proxiesHashGate unlock];
NSParameterAssert(!p || [p connectionForProxy] == self);
return p;
}
- (void) addProxy: (Proxy*) aProxy
{
unsigned target = [aProxy targetForProxy];
NSParameterAssert (is_valid);
NSParameterAssert(aProxy->isa == [Proxy class]);
NSParameterAssert([aProxy connectionForProxy] == self);
[proxiesHashGate lock];
if (NSMapGet (remote_proxies, (void*)target))
[NSException raise: NSGenericException
format: @"Trying to add the same proxy twice"];
NSMapInsert (remote_proxies, (void*)target, aProxy);
[proxiesHashGate unlock];
}
- (BOOL) includesProxyForTarget: (unsigned)target
{
BOOL ret;
/* Don't assert (is_valid); */
[proxiesHashGate lock];
ret = NSMapGet (remote_proxies, (void*)target) ? YES : NO;
[proxiesHashGate unlock];
return ret;
}
- (BOOL) includesLocalObject: anObj
{
BOOL ret;
/* Don't assert (is_valid); */
[proxiesHashGate lock];
ret = NSMapGet (local_targets, (void*)anObj) ? YES : NO;
[proxiesHashGate unlock];
return ret;
}
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
/* Check all connections.
Proxy needs to use this when decoding a local object in order to
make sure the target address is a valid object. It is not enough
for the Proxy to check the Proxy's connection only (using
-includesLocalObject), because the proxy may have come from a
triangle connection. */
+ (BOOL) includesLocalObject: anObj
{
BOOL ret;
/* Don't assert (is_valid); */
NSParameterAssert (all_connections_local_targets);
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
[proxiesHashGate lock];
ret = NSMapGet (all_connections_local_targets, (void*)anObj) ? YES : NO;
[proxiesHashGate unlock];
return ret;
}
/* Pass nil to remove any reference keyed by aPort. */
+ (void) setRootObject: anObj forInPort: (InPort*)aPort
{
id oldRootObject = [self rootObjectForInPort: aPort];
NSParameterAssert ([aPort isValid]);
/* xxx This retains aPort? How will aPort ever get dealloc'ed? */
if (oldRootObject != anObj)
{
if (anObj)
{
[root_object_dictionary_gate lock];
[root_object_dictionary putObject: anObj atKey: aPort];
[root_object_dictionary_gate unlock];
}
else /* anObj == nil && oldRootObject != nil */
{
[root_object_dictionary_gate lock];
[root_object_dictionary removeObjectAtKey: aPort];
[root_object_dictionary_gate unlock];
}
}
}
+ rootObjectForInPort: (InPort*)aPort
{
id ro;
[root_object_dictionary_gate lock];
ro = [root_object_dictionary objectAtKey:aPort];
[root_object_dictionary_gate unlock];
return ro;
}
- setRootObject: anObj
{
[[self class] setRootObject: anObj forInPort: in_port];
return self;
}
- rootObject
{
return [[self class] rootObjectForInPort: in_port];
}
/* Accessing ivars */
- (int) outTimeout
{
return out_timeout;
}
- (int) inTimeout
{
return in_timeout;
}
- (void) setOutTimeout: (int)to
{
out_timeout = to;
}
- (void) setInTimeout: (int)to
{
in_timeout = to;
}
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
- (Class) inPortClass
{
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
return in_port_class;
}
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
- (Class) outPortClass
{
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
return out_port_class;
}
- (void) setInPortClass: (Class) aPortClass
{
in_port_class = aPortClass;
}
- (void) setOutPortClass: (Class) aPortClass
{
out_port_class = aPortClass;
}
- (Class) proxyClass
{
/* we might replace this with a per-Connection proxy class. */
return default_proxy_class;
}
- (Class) encodingClass
{
return encoding_class;
}
- (Class) decodingClass
{
/* we might replace this with a per-Connection class. */
return default_decoding_class;
}
- outPort
{
return out_port;
}
- inPort
{
return in_port;
}
- delegate
{
return delegate;
}
- (void) setDelegate: anObj
{
delegate = anObj;
}
/* Support for cross-connection const-ptr cache. */
- (unsigned) _encoderCreateReferenceForConstPtr: (const void*)ptr
{
unsigned xref;
NSParameterAssert (is_valid);
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
/* This must match the assignment of xref in _decoderCreateRef... */
xref = NSCountMapTable (outgoing_const_ptr_2_xref) + 1;
NSParameterAssert (! NSMapGet (outgoing_const_ptr_2_xref, (void*)xref));
NSMapInsert (outgoing_const_ptr_2_xref, ptr, (void*)xref);
return xref;
}
- (unsigned) _encoderReferenceForConstPtr: (const void*)ptr
{
NSParameterAssert (is_valid);
return (unsigned) NSMapGet (outgoing_const_ptr_2_xref, ptr);
}
- (unsigned) _decoderCreateReferenceForConstPtr: (const void*)ptr
{
unsigned xref;
NSParameterAssert (is_valid);
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
/* This must match the assignment of xref in _encoderCreateRef... */
xref = NSCountMapTable (incoming_xref_2_const_ptr) + 1;
NSMapInsert (incoming_xref_2_const_ptr, (void*)xref, ptr);
return xref;
}
- (const void*) _decoderConstPtrAtReference: (unsigned)xref
{
NSParameterAssert (is_valid);
return NSMapGet (incoming_xref_2_const_ptr, (void*)xref);
}
/* Prevent trying to encode the connection itself */
- (void) encodeWithCoder: anEncoder
{
[self shouldNotImplement:_cmd];
}
+ newWithCoder: aDecoder;
{
[self shouldNotImplement:_cmd];
return self;
}
/* Shutting down and deallocating. */
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
/* We register this method with NotificationDispatcher for when a port dies. */
- (void) portIsInvalid: notification
{
id port = [notification object];
NSParameterAssert (is_valid);
if (debug_connection)
fprintf (stderr, "Received port invalidation notification for "
"connection 0x%x\n\t%s\n", (unsigned)self,
[[port description] cStringNoCopy]);
/* We shouldn't be getting any port invalidation notifications,
except from our own ports; this is how we registered ourselves
with the NotificationDispatcher in
+newForInPort:outPort:ancestorConnection. */
NSParameterAssert (port == in_port || port == out_port);
/* xxx This also needs to be done properly in cases where the
Connection invalidates itself. */
/* Remove ourselves from the in_port_2_ancestor, if necessary. */
{
id ancestor;
if ([port isKindOfClass: [InPort class]]
&& (self == (ancestor = NSMapGet (in_port_2_ancestor, port))))
NSMapRemove (in_port_2_ancestor, port);
}
[self invalidate];
/* xxx Anything else? */
}
/* xxx This needs locks */
- (void) invalidate
{
if (is_valid)
{
is_valid = 0;
/* xxx Note: this is causing us to send a shutdown message
to the connection that shut *us* down. Don't do that.
Well, perhaps it's a good idea just in case other side didn't really
send us the shutdown; this way we let them know we're going away */
#if 0
[self shutdown];
#endif
if (debug_connection)
fprintf(stderr, "Invalidating connection 0x%x\n\t%s\n\t%s\n",
(unsigned)self,
[[in_port description] cStringNoCopy],
[[out_port description] cStringNoCopy]);
[NotificationDispatcher
postNotificationName: ConnectionBecameInvalidNotification
object: self];
/* xxx Anything else? */
/* xxx Yes, somehow Proxies of connections with invalid ports
are being asked to encode themselves. */
}
}
- (BOOL) isValid
{
return is_valid;
}
/* This needs locks */
- (void) dealloc
{
if (debug_connection)
printf("deallocating 0x%x\n", (unsigned)self);
[self invalidate];
[connection_array removeObject: self];
/* Remove rootObject from root_object_dictionary
if this is last connection */
if (![Connection connectionsCountWithInPort:in_port])
[Connection setRootObject:nil forInPort:in_port];
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
[NotificationDispatcher removeObserver: self];
[in_port release];
[out_port release];
[proxiesHashGate lock];
NSFreeMapTable (remote_proxies);
NSFreeMapTable (local_targets);
NSFreeMapTable (incoming_xref_2_const_ptr);
NSFreeMapTable (outgoing_const_ptr_2_xref);
[proxiesHashGate unlock];
[super dealloc];
}
@end
/* Notification Strings. */
NSString *ConnectionBecameInvalidNotification
= @"ConnectionBecameInvalidNotification";
(default_in_port_class, default_out_port_class): New static variables, replacing default_port_class. (all_connections_local_targets): New map table; not used yet, though. (debug_connection): Temporarily set to 1. ([Connection +initialize]): Set new static vars. ([Connection +setDefaultInPortClass:]): New method. ([Connection +defaultInPortClass]): New method. ([Connection +setDefaultOutPortClass:]): New method. ([Connection +defaultOutPortClass]): New method. ([Connection -init]): Use new default_in_port_class. ([Connection +new]): Likewise. ([Connection +newWithRootObject:]): Likewise. ([Connection +newRegisteringAtName:withRootObject:]): Likewise. ([Connection +rootProxyAtName:onHost:]): Likewise. ([Connection +rootProxyAtPort:]): Likewise. ([Connection +newForInPort:outPort:ancestorConnection:]): Assert the in port. Embellish the debugging message to print the in port and out port. Set the new connection's in port and out port ivars. Register ourselves as observers of port invalidation with the NotificationDispatcher. Post a notification that a new connection was created. ([Connection -runConnectionWithTimeout:]): Use _serviceReceivedRequestsWithTimeout:. ([Connection -_newReceivedRmcWithTimeout:]): Use decodingClass, not encodingClass. ([Connection -_serviceReceivedRequestsWithTimeout:]): Method name changed from -newReceivedReplyRmcWithSequenceNumber:. ([Connection +includesLocalObject:]): New method; still needs more infrastructure to work, though. ([Connection -inPortClass]): New method. ([Connection -outPortClass]): New method. ([Connection -setInPortClass:aPortClass]): New method. ([Connection -setOutPortClass:aPortClass]): New method. ([Connection -_encoderCreateReferenceForConstPtr:]): Add 1 to map table count to get xref. ([Connection -_decoderCreateReferenceForConstPtr:]): Likewise. ([Connection -dealloc]): Remove ourselves from the NotificationDispatcher. (ConnectionWasCreatedNotification): New notification string. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1057 72102866-910b-0410-8b05-ffd578937521
1996-03-06 14:05:36 +00:00
NSString *ConnectionWasCreatedNotification
= @"ConnectionWasCreatedNotification";
/* RunLoop modes */
NSString *RunLoopConnectionReplyMode
= @"RunLoopConnectionReplyMode";