[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-multimedia
Subject:    [PATCH] MCOP reference counting fix
From:       Stefan Westerfeld <stefan () space ! twc ! de>
Date:       2000-09-28 11:21:51
[Download RAW message or body]

Hi!

Probably while running aRts, you've already seen this

   _referenceClean: found unused object marked by _copyRemote => releasing

message. It is a warning of the reference counting, that indicates that
something went wrong with _copyRemote. This *can* happen due to server/app
crashes and stuff like that, but shouldn't happen during "normal use".

However, it did, because I forgot one case. Here is a patch that fixes it.
It does so by adding _cancelCopyRemote, which we call in the case that we
receive an object reference from wire, which however points to an object
which lives on our server. Without this patch, doing this would lead to
this _copyRemote warning (because as the object is not remote, there is
no _useRemote). I'll apply it soon, if there are no objections.

I've documented the NEW behaviour in mcop/doc/using-references.html (last
section: internals). Please ask if my reference counting documentation is
unclear.

   Cu... Stefan
-- 
  -* Stefan Westerfeld, stefan@space.twc.de (PGP!), Hamburg/Germany
     KDE Developer, project infos at http://space.twc.de/~stefan/kde *-         

["20000928-reference-copy-cancel.diff" (text/plain)]

Index: mcop/core.cc
===================================================================
RCS file: /home/kde/kdelibs/arts/mcop/core.cc,v
retrieving revision 1.43
diff -u -r1.43 core.cc
--- mcop/core.cc	2000/09/08 21:30:22	1.43
+++ mcop/core.cc	2000/09/28 11:05:50
@@ -763,8 +763,13 @@
 {
 	Arts::InterfaceRepo_base *result;
 	result = (Arts::InterfaceRepo_base \
                *)Arts::Dispatcher::the()->connectObjectLocal(r,"Arts::InterfaceRepo");
                
-	if(!result)
+	if(result)
 	{
+		if(!needcopy)
+			result->_cancelCopyRemote();
+	}
+	else
+	{
 		Arts::Connection *conn = Arts::Dispatcher::the()->connectObjectRemote(r);
 		if(conn)
 		{
@@ -1116,7 +1121,12 @@
 {
 	Arts::FlowSystemSender_base *result;
 	result = (Arts::FlowSystemSender_base \
                *)Arts::Dispatcher::the()->connectObjectLocal(r,"Arts::FlowSystemSender");
                
-	if(!result)
+	if(result)
+	{
+		if(!needcopy)
+			result->_cancelCopyRemote();
+	}
+	else
 	{
 		Arts::Connection *conn = Arts::Dispatcher::the()->connectObjectRemote(r);
 		if(conn)
@@ -1235,8 +1245,13 @@
 {
 	Arts::FlowSystemReceiver_base *result;
 	result = (Arts::FlowSystemReceiver_base \
                *)Arts::Dispatcher::the()->connectObjectLocal(r,"Arts::FlowSystemReceiver");
                
-	if(!result)
+	if(result)
 	{
+		if(!needcopy)
+			result->_cancelCopyRemote();
+	}
+	else
+	{
 		Arts::Connection *conn = Arts::Dispatcher::the()->connectObjectRemote(r);
 		if(conn)
 		{
@@ -1361,7 +1376,12 @@
 {
 	Arts::FlowSystem_base *result;
 	result = (Arts::FlowSystem_base \
                *)Arts::Dispatcher::the()->connectObjectLocal(r,"Arts::FlowSystem");
-	if(!result)
+	if(result)
+	{
+		if(!needcopy)
+			result->_cancelCopyRemote();
+	}
+	else
 	{
 		Arts::Connection *conn = Arts::Dispatcher::the()->connectObjectRemote(r);
 		if(conn)
@@ -1666,8 +1686,13 @@
 {
 	Arts::GlobalComm_base *result;
 	result = (Arts::GlobalComm_base \
                *)Arts::Dispatcher::the()->connectObjectLocal(r,"Arts::GlobalComm");
-	if(!result)
+	if(result)
 	{
+		if(!needcopy)
+			result->_cancelCopyRemote();
+	}
+	else
+	{
 		Arts::Connection *conn = Arts::Dispatcher::the()->connectObjectRemote(r);
 		if(conn)
 		{
@@ -1853,7 +1878,12 @@
 {
 	Arts::TmpGlobalComm_base *result;
 	result = (Arts::TmpGlobalComm_base \
                *)Arts::Dispatcher::the()->connectObjectLocal(r,"Arts::TmpGlobalComm");
                
-	if(!result)
+	if(result)
+	{
+		if(!needcopy)
+			result->_cancelCopyRemote();
+	}
+	else
 	{
 		Arts::Connection *conn = Arts::Dispatcher::the()->connectObjectRemote(r);
 		if(conn)
@@ -1958,8 +1988,13 @@
 {
 	Arts::TraderOffer_base *result;
 	result = (Arts::TraderOffer_base \
                *)Arts::Dispatcher::the()->connectObjectLocal(r,"Arts::TraderOffer");
-	if(!result)
+	if(result)
 	{
+		if(!needcopy)
+			result->_cancelCopyRemote();
+	}
+	else
+	{
 		Arts::Connection *conn = Arts::Dispatcher::the()->connectObjectRemote(r);
 		if(conn)
 		{
@@ -2116,7 +2151,12 @@
 {
 	Arts::TraderQuery_base *result;
 	result = (Arts::TraderQuery_base \
                *)Arts::Dispatcher::the()->connectObjectLocal(r,"Arts::TraderQuery");
-	if(!result)
+	if(result)
+	{
+		if(!needcopy)
+			result->_cancelCopyRemote();
+	}
+	else
 	{
 		Arts::Connection *conn = Arts::Dispatcher::the()->connectObjectRemote(r);
 		if(conn)
Index: mcop/object.cc
===================================================================
RCS file: /home/kde/kdelibs/arts/mcop/object.cc,v
retrieving revision 1.39
diff -u -r1.39 object.cc
--- mcop/object.cc	2000/09/12 07:29:19	1.39
+++ mcop/object.cc	2000/09/28 11:05:55
@@ -369,6 +369,25 @@
 	_remoteUsers.push_back(conn);
 }
 
+/*
+ * This is needed when we've received an object from wire which we now
+ * hold locally. Of course it has been _copyRemote()d (rightly so), but
+ * we will not use it remotely, so we need to cancel the _copyRemote().
+ *
+ * Added to _base due to BC.
+ */
+void Object_base::_cancelCopyRemote()
+{
+	assert(_location() == objectIsLocal);
+	cerr << _interfaceName() << "_cancelCopyRemote()" << endl;
+	if(_skel()->_remoteSendCount == 0)
+	{
+		cerr << "warning: _cancelCopyRemote without prior _copyRemote() -"
+					" this might fail sometimes" << endl;
+	}
+	else _skel()->_remoteSendCount--;
+}
+
 void Object_skel::_disconnectRemote(Connection *conn)
 {
 	//cout << "_disconnectRemote();" << endl;
@@ -408,8 +427,8 @@
 		}
 		else
 		{
-			cerr << "_referenceClean: found unused object"
-			        " marked by _copyRemote => releasing" << endl;
+			cerr << "_referenceClean: found unused " << _interfaceName()
+			     << " object marked by _copyRemote => releasing" << endl;
 			_remoteSendCount = 0;
 			_refCnt++;
 			_release();
@@ -844,7 +863,12 @@
 {
 	Object_base *result;
 	result = (Object_base *)Dispatcher::the()->connectObjectLocal(r,"Object");
-	if(!result)
+	if(result)
+	{
+		if(!needcopy)
+			result->_cancelCopyRemote();
+	}
+	else
 	{
 		Connection *conn = Dispatcher::the()->connectObjectRemote(r);
 		if(conn)
Index: mcop/object.h
===================================================================
RCS file: /home/kde/kdelibs/arts/mcop/object.h,v
retrieving revision 1.35
diff -u -r1.35 object.h
--- mcop/object.h	2000/09/12 07:29:19	1.35
+++ mcop/object.h	2000/09/28 11:05:56
@@ -136,6 +136,9 @@
 	virtual void _useRemote() = 0;
 	virtual void _releaseRemote() = 0;
 
+	// BC issue: added _cancelCopyRemote here to avoid virtual function
+	void _cancelCopyRemote();
+
 	void _addWeakReference(WeakReferenceBase *reference);
 	void _removeWeakReference(WeakReferenceBase *reference);
 
Index: mcopidl/mcopidl.cc
===================================================================
RCS file: /home/kde/kdelibs/arts/mcopidl/mcopidl.cc,v
retrieving revision 1.66
diff -u -r1.66 mcopidl.cc
--- mcopidl/mcopidl.cc	2000/09/08 21:30:22	1.66
+++ mcopidl/mcopidl.cc	2000/09/28 11:06:06
@@ -1910,7 +1910,12 @@
 		fprintf(source,
 		"\tresult = (%s_base *)Arts::Dispatcher::the()->connectObjectLocal(r,\"%s\");\n",
 										d.name.c_str(),d.name.c_str());
-		fprintf(source,"\tif(!result)\n");
+		fprintf(source,"\tif(result)\n");
+		fprintf(source,"\t{\n");
+		fprintf(source,"\t\tif(!needcopy)\n");
+		fprintf(source,"\t\t\tresult->_cancelCopyRemote();\n");
+		fprintf(source,"\t}\n");
+		fprintf(source,"\telse\n");
 		fprintf(source,"\t{\n");
 		fprintf(source,"\t\tArts::Connection *conn = "
 							"Arts::Dispatcher::the()->connectObjectRemote(r);\n");


_______________________________________________
Kde-multimedia mailing list
Kde-multimedia@master.kde.org
http://master.kde.org/mailman/listinfo/kde-multimedia


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic