Permission to commit ...
- From: Michael Meeks <michael ximian com>
- To: Elliot Lee <sopwith redhat com>
- Cc: orbit-list gnome org
- Subject: Permission to commit ...
- Date: Thu, 24 May 2001 16:45:54 -0400 (EDT)
Hi there,
The attached patches sort out the referncing mahem going on inside
linc & the giop code - at least, they work for me and stop the ORB leaking
like a sieve.
Here is the problem they address:
There are two ways to create a linc-connection,
a) ORBit_object_get_connection
b) linc_server_handle_io
In case a) the client side:
+ the connection can be closed by a HUP
+ but the Object ref still has a pointer to the connection
so the connection cannot be freed.
+ Consequently there is an 'invalidate connection' step
followed by a 'destroy connection' step when the Object
reference is released.
In case b) the server side:
+ the connection can be closed by a HUP, and at this point
it should release all the resources associated with it.
My solution: [ a ref == a g_object_ref ]
+ while the watch is connected [ waiting for an error
condition ] the connection has a ref on itself.
+ the associated object reference also holds a ref
+ when the watch is disconnected - such as eg. as the
connection is being invalidated, the connection is
unreffed
- if case a) there is still a ref on the object
so, the connection is closed, but the pointer is
still valid.
- if case b) there was only the self reference so
the connection is torn down cleanly.
So, the attached patches implement this - and indeed memory usage
is nicely static. The patches are aginst the ORBit2 orbit-small branch and
linc HEAD. The issue is that committing the linc patch will break the [
already broken ] ORBit2 HEAD even further, so can you advise ?
Thanks,
Michael.
--
mmeeks gnu org <><, Pseudo Engineer, itinerant idiot
? elliot
? include/orbit/orb-core/orbit-interface.h
? src/orb/orb-core/orbit-interface.h
? src/orb/orb-core/runidl_iface
? test/everything/server.log
? test/everything/client.log
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/ORBit2/ChangeLog,v
retrieving revision 1.12.2.25
diff -u -r1.12.2.25 ChangeLog
--- ChangeLog 2001/05/24 11:58:11 1.12.2.25
+++ ChangeLog 2001/05/24 20:36:43
@@ -1,9 +1,25 @@
+2001-05-25 Michael Meeks <michael ximian com>
+
+ * src/orb/orb-core/corba-context.c (CORBA_Context_set_one_value):
+ remove the hash table value, so we don't screw up the key allocation.
+
2001-05-24 Michael Meeks <michael ximian com>
+ * src/orb/GIOP/giop-connection.c (giop_connection_initiate):
+ reference the connection before returning it, if it wasn't
+ looked up in the list.
+ (giop_connection_remove_by_orb): fix serious brokenness.
+ (giop_connection_close): publicise.
+ (giop_connection_shutdown): remove the connection from the
+ connection list.
+ (giop_connection_unref): remove last unref sillies.
+
* src/orb/orb-core/corba-object.c (g_CORBA_Object_equal): uglify,
we need to be able to scan for MULTIPLE_COMPONENTS profiles in
order to do the GIOP profile comparison (get_mci): impl helper.
(IOP_Profile_equal): similarly uglify.
+ (CORBA_Object_release_cb): close the connection and
+ unref it.
* src/orb/poa/poa.c (ORBit_POA_oid_to_ref): set the profile_type
on the iiop profile.
Index: include/orbit/GIOP/giop-connection.h
===================================================================
RCS file: /cvs/gnome/ORBit2/include/orbit/GIOP/giop-connection.h,v
retrieving revision 1.15
diff -u -r1.15 giop-connection.h
--- include/orbit/GIOP/giop-connection.h 2000/10/31 23:37:49 1.15
+++ include/orbit/GIOP/giop-connection.h 2001/05/24 20:36:43
@@ -53,5 +53,6 @@
GIOPVersion giop_version);
void giop_connection_unref(GIOPConnection *cnx);
void giop_connection_remove_by_orb(gpointer match_orb_data);
+void giop_connection_close (GIOPConnection *cnx);
#endif
Index: src/orb/GIOP/giop-connection.c
===================================================================
RCS file: /cvs/gnome/ORBit2/src/orb/GIOP/giop-connection.c,v
retrieving revision 1.19.2.3
diff -u -r1.19.2.3 giop-connection.c
--- src/orb/GIOP/giop-connection.c 2001/05/24 10:12:18 1.19.2.3
+++ src/orb/GIOP/giop-connection.c 2001/05/24 20:36:43
@@ -23,6 +23,7 @@
static void
giop_connection_list_add(GIOPConnection *cnx)
{
+ g_return_if_fail (cnx != NULL);
cnx_list.list = g_list_prepend(cnx_list.list, cnx);
}
@@ -104,7 +105,7 @@
O_MUTEX_INIT(cnx->outgoing_mutex);
}
-static void
+void
giop_connection_close (GIOPConnection *cnx)
{
if(cnx->parent.status == LINC_DISCONNECTED)
@@ -125,7 +126,7 @@
}
static void
-giop_connection_shutdown (GObject *obj)
+giop_connection_shutdown (GObject *obj)
{
GIOPConnection *cnx = (GIOPConnection *)obj;
@@ -133,6 +134,10 @@
O_MUTEX_DESTROY(cnx->incoming_mutex);
O_MUTEX_DESTROY(cnx->outgoing_mutex);
+ O_MUTEX_LOCK(cnx_list.lock);
+ giop_connection_list_remove(cnx);
+ O_MUTEX_UNLOCK(cnx_list.lock);
+
if(parent_class->shutdown)
parent_class->shutdown(obj);
}
@@ -265,11 +270,7 @@
if(!cnx)
return;
- O_MUTEX_LOCK(cnx_list.lock);
- if(G_OBJECT(cnx)->ref_count == 1)
- giop_connection_list_remove(cnx);
g_object_unref(G_OBJECT(cnx));
- O_MUTEX_UNLOCK(cnx_list.lock);
}
/* This will just create the fd, do the connect and all, and then call
@@ -299,6 +300,8 @@
}
else
giop_connection_list_add(cnx);
+
+ g_object_ref (G_OBJECT(cnx));
}
O_MUTEX_UNLOCK(cnx_list.lock);
@@ -309,16 +312,18 @@
void
giop_connection_remove_by_orb(gpointer match_orb_data)
{
- GList *link;
+ GList *l, *next;
O_MUTEX_LOCK(cnx_list.lock);
- for (link = cnx_list.list; link; )
+ for (l = cnx_list.list; l; l = next)
{
- GIOPConnection *cnx = link->data;
- link = link->next;
- if ( cnx->orb_data == match_orb_data )
- cnx_list.list = g_list_delete_link(cnx_list.list, link);
- giop_connection_close (cnx);
+ GIOPConnection *cnx = l->data;
+
+ next = l->next;
+ if ( cnx->orb_data == match_orb_data ) {
+ cnx_list.list = g_list_delete_link(cnx_list.list, l);
+ giop_connection_close (cnx);
+ }
}
O_MUTEX_UNLOCK(cnx_list.lock);
}
Index: src/orb/orb-core/corba-context.c
===================================================================
RCS file: /cvs/gnome/ORBit2/src/orb/orb-core/corba-context.c,v
retrieving revision 1.5.2.3
diff -u -r1.5.2.3 corba-context.c
--- src/orb/orb-core/corba-context.c 2001/05/18 18:45:30 1.5.2.3
+++ src/orb/orb-core/corba-context.c 2001/05/24 20:36:43
@@ -98,6 +98,7 @@
ctx->mappings = g_hash_table_new(g_str_hash, g_str_equal);
if(g_hash_table_lookup_extended(ctx->mappings, prop_name, &old_nom, &old_value)) {
+ g_hash_table_remove (ctx->mappings, prop_name);
g_free(old_nom);
g_free(old_value);
}
Index: src/orb/orb-core/corba-object.c
===================================================================
RCS file: /cvs/gnome/ORBit2/src/orb/orb-core/corba-object.c,v
retrieving revision 1.19.2.9
diff -u -r1.19.2.9 corba-object.c
--- src/orb/orb-core/corba-object.c 2001/05/24 11:58:11 1.19.2.9
+++ src/orb/orb-core/corba-object.c 2001/05/24 20:36:43
@@ -60,7 +60,8 @@
g_hash_table_remove (objrefs, obj);
if (obj->connection) {
-/* g_warning("Release object '%p's connection", obj);*/
+/* g_warning("Release object '%p's connection", obj); */
+ giop_connection_close (obj->connection);
giop_connection_unref (obj->connection);
}
@@ -303,7 +304,6 @@
if(IOP_profile_get_info(obj, pi, &iiop_version, &proto,
&host, &service, &is_ssl, &oki, tbuf))
{
- g_warning ("Initiated new connection on '%s'", obj->type_id);
obj->connection =
giop_connection_initiate(proto, host, service,
is_ssl?LINC_CONNECTION_SSL:0, iiop_version);
Index: test/everything/Makefile.am
===================================================================
RCS file: /cvs/gnome/ORBit2/test/everything/Makefile.am,v
retrieving revision 1.2.2.15
diff -u -r1.2.2.15 Makefile.am
--- test/everything/Makefile.am 2001/05/24 07:38:19 1.2.2.15
+++ test/everything/Makefile.am 2001/05/24 20:36:43
@@ -19,14 +19,14 @@
LDADD = $(top_builddir)/src/orb/libORBit-2.la \
$(LINC_LIBS) \
- ${GLIB_LIBS}
+ ${GLIB_LIBS}
+# -lefence
LDFLAGS = -static
client_SOURCES=${EVERYTHING_BUILT} client.c everything.idl constants.h
client_DEPENDENCES=${EVERYTHING_BUILT} $(included_src)
client_LDADD = $(LDADD)
-# -lefence
included_src = \
basicServer.c \
? elliot
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/linc/ChangeLog,v
retrieving revision 1.6
diff -u -r1.6 ChangeLog
--- ChangeLog 2001/05/24 09:57:48 1.6
+++ ChangeLog 2001/05/24 20:36:30
@@ -1,4 +1,16 @@
+2001-05-25 Michael Meeks <michael ximian com>
+
+ * src/linc-connection.c (linc_source_remove): split from
+ (linc_connection_shutdown): here, and release the self
+ reference whilst watching.
+ (linc_connection_real_state_changed): use linc_source_remove.
+ (linc_connection_connected): hold a ref over the state_changed
+ emissions.
+
2001-05-24 Michael Meeks <michael ximian com>
+
+ * src/linc-connection.c (linc_connection_connected):
+ unref the connection object on disconnection.
* src/linc-server.c (linc_server_destroy):
protect against multiple shutdowns, and rename to
Index: src/linc-connection.c
===================================================================
RCS file: /cvs/gnome/linc/src/linc-connection.c,v
retrieving revision 1.20
diff -u -r1.20 linc-connection.c
--- src/linc-connection.c 2001/05/24 09:57:49 1.20
+++ src/linc-connection.c 2001/05/24 20:36:30
@@ -61,13 +61,22 @@
}
static void
-linc_connection_shutdown (GObject *obj)
+linc_source_remove (LINCConnection *cnx, gboolean unref)
{
- LINCConnection *cnx = (LINCConnection *)obj;
-
- if(cnx->tag)
+ if(cnx->tag) {
g_assert (g_source_remove(cnx->tag));
+ if (unref)
+ g_object_unref (G_OBJECT (cnx));
+ }
cnx->tag = 0;
+}
+
+static void
+linc_connection_shutdown (GObject *obj)
+{
+ LINCConnection *cnx = (LINCConnection *)obj;
+
+ linc_source_remove (cnx, FALSE);
g_free(cnx->remote_host_info);
cnx->remote_host_info = NULL;
g_free(cnx->remote_serv_info);
@@ -89,6 +98,9 @@
int rv, n;
socklen_t n_size = sizeof(n);
gboolean retval = TRUE;
+ gboolean disconnected = FALSE;
+
+ g_object_ref (G_OBJECT (cnx));
switch(cnx->status)
{
@@ -104,16 +116,22 @@
linc_connection_connected, cnx);
retval = FALSE;
}
- else
+ else {
linc_connection_state_changed(cnx, LINC_DISCONNECTED);
+ disconnected = TRUE;
+ }
break;
- case LINC_CONNECTED:
+ case LINC_CONNECTED: {
linc_connection_state_changed(cnx, LINC_DISCONNECTED);
+ disconnected = TRUE;
break;
+ }
default:
break;
}
+ g_object_unref (G_OBJECT (cnx));
+
return retval;
}
@@ -138,15 +156,15 @@
linc_connection_connected, cnx);
break;
case LINC_CONNECTING:
- if(cnx->tag)
- g_assert (g_source_remove(cnx->tag));
+ linc_source_remove (cnx, FALSE);
cnx->tag = g_io_add_watch(cnx->gioc, G_IO_OUT|G_IO_ERR|G_IO_HUP|G_IO_NVAL, linc_connection_connected, cnx);
break;
case LINC_DISCONNECTED:
- if(cnx->tag)
- g_assert (g_source_remove(cnx->tag));
- cnx->tag = 0;
- close(cnx->fd);
+/* g_warning ("Linc disconnected tag %d fd '%d'",
+ cnx->tag, cnx->fd);*/
+ linc_source_remove (cnx, TRUE);
+ if (cnx->fd >= 0)
+ close(cnx->fd);
cnx->fd = -1;
break;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]