From kde-multimedia Fri Sep 29 15:22:37 2000 From: Stefan Westerfeld Date: Fri, 29 Sep 2000 15:22:37 +0000 To: kde-multimedia Subject: [PATCH] artsd streams memory leak X-MARC-Message: https://marc.info/?l=kde-multimedia&m=97024087505040 MIME-Version: 1 Content-Type: multipart/mixed; boundary="--lrZ03NoBR/3+SXJZ" --lrZ03NoBR/3+SXJZ Content-Type: text/plain; charset=us-ascii Hi! Any incoming stream of samples (like caused by xmms plugin, artsdsp xmms, quake w/ arts, aRts C API, artscat) causes a memory leak in the CVS version of aRts. This happens since some objects which are used from transfer, namely FlowSystemSender & FlowSystemReceiver are not freed. You'll also see this if you exit artsd, which after having at least one stream connected prints out warnings about remaining objects. Here is a patch that fixes it. Freeing the connection properly triggered quite a few segfaults in various combinations (such as killing artscat with ctrl+C just while it was initializing), but I hope the patch catches them all. If there are no objections, I'll commit it tomorrow. Cu... Stefan -- -* Stefan Westerfeld, stefan@space.twc.de (PGP!), Hamburg/Germany KDE Developer, project infos at http://space.twc.de/~stefan/kde *- --lrZ03NoBR/3+SXJZ Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="20000929-memleak-fix.diff" Index: flow/asyncschedule.cc =================================================================== RCS file: /home/kde/kdelibs/arts/flow/asyncschedule.cc,v retrieving revision 1.10 diff -u -u -r1.10 asyncschedule.cc --- flow/asyncschedule.cc 2000/09/28 22:42:37 1.10 +++ flow/asyncschedule.cc 2000/09/29 15:12:41 @@ -23,6 +23,7 @@ #include "asyncschedule.h" #include "debug.h" #include +#include using namespace std; using namespace Arts; @@ -35,6 +36,30 @@ stream = (GenericAsyncStream *)ptr; stream->channel = this; stream->_notifyID = notifyID = parent->object()->_mkNotifyID(); + + sender = FlowSystemSender::null(); +} + +ASyncPort::~ASyncPort() +{ + /* + * tell all outstanding packets that we don't exist any longer, so that + * if they feel like they need to confirm they have been processed now, + * they don't talk to an no longer existing object about it + */ + while(!sent.empty()) + { + sent.front()->channel = 0; + sent.pop_front(); + } + + /* + * disconnect remote connection (if there was one) + * TODO: remote multicasting doesn't work (probably also not too + * important) + */ + if(!sender.isNull()) + sender.disconnect(); } //-------------------- GenericDataChannel interface ------------------------- @@ -62,6 +87,20 @@ void ASyncPort::processedPacket(GenericDataPacket *packet) { + int count = 0; + list::iterator i, nexti; + for(i=sent.begin(); i != sent.end(); i = nexti) + { + nexti = i; nexti++; + + if(*i == packet) + { + count++; + sent.erase(i); + } + } + assert(count == 1); + #ifdef DEBUG_ASYNC_TRANSFER cout << "port::processedPacket" << endl; #endif @@ -95,6 +134,7 @@ cout << "sending notification " << n.ID << endl; #endif NotificationManager::the()->send(n); + sent.push_back(packet); } } else @@ -169,6 +209,7 @@ n.receiver = netsend; n.ID = netsend->notifyID(); subscribers.push_back(n); + sender = FlowSystemSender::_from_base(netsend->_copy()); } long ASyncNetSend::notifyID() @@ -202,6 +243,16 @@ receiveHandlerID = newReceiver.receiveHandlerID(); } +void ASyncNetSend::disconnect() +{ + if(!receiver.isNull()) + { + FlowSystemReceiver r = receiver; + receiver = FlowSystemReceiver::null(); + r.disconnect(); + } +} + /* dispatching function for custom message */ static void _dispatch_ASyncNetReceive_receive(void *object, Buffer *buffer) @@ -222,6 +273,17 @@ _addCustomMessageHandler(_dispatch_ASyncNetReceive_receive,this); } +ASyncNetReceive::~ASyncNetReceive() +{ + /* tell outstanding packets that we don't exist any longer */ + while(!sent.empty()) + { + sent.front()->channel = 0; + sent.pop_front(); + } + delete stream; +} + long ASyncNetReceive::receiveHandlerID() { return _receiveHandlerID; @@ -234,6 +296,7 @@ dp->useCount = 1; gotPacketNotification.data = dp; NotificationManager::the()->send(gotPacketNotification); + sent.push_back(dp); } /* @@ -251,8 +314,29 @@ */ void ASyncNetReceive::processedPacket(GenericDataPacket *packet) { + // FIXME: HACK HACK HACK HACK (protect myself against disconnections) + _copy(); + sent.remove(packet); + arts_debug("[ANR] freePacket"); stream->freePacket(packet); - sender.processed(); + arts_debug("[ANR] processed"); + if(!sender.isNull()) + { + FlowSystemSender xsender = sender; // FIXME: MORE HACK + xsender.processed(); + } + arts_debug("[ANR] ok"); + _release(); +} + +void ASyncNetReceive::disconnect() +{ + if(!sender.isNull()) + { + FlowSystemSender s = sender; + sender = FlowSystemSender::null(); + s.disconnect(); + } } void ASyncNetReceive::sendPacket(GenericDataPacket *packet) Index: flow/asyncschedule.h =================================================================== RCS file: /home/kde/kdelibs/arts/flow/asyncschedule.h,v retrieving revision 1.8 diff -u -u -r1.8 asyncschedule.h --- flow/asyncschedule.h 2000/05/17 22:48:20 1.8 +++ flow/asyncschedule.h 2000/09/29 15:12:41 @@ -26,6 +26,8 @@ #include "synthschedule.h" #include "datapacket.h" +#include + namespace Arts { class ASyncNetSend : public FlowSystemSender_skel @@ -42,6 +44,7 @@ void notify(const Notification& notification); void processed(); void setReceiver(FlowSystemReceiver receiver); + void disconnect(); }; class ASyncNetReceive : public FlowSystemReceiver_skel, @@ -51,10 +54,12 @@ GenericAsyncStream *stream; FlowSystemSender sender; Notification gotPacketNotification; + list sent; long _receiveHandlerID; public: ASyncNetReceive(ASyncPort *port, FlowSystemSender sender); + ~ASyncNetReceive(); // GenericDataChannel interface void processedPacket(GenericDataPacket *packet); @@ -65,6 +70,7 @@ // FlowSystemReceiver interface long receiveHandlerID(); + void disconnect(); void receive(Buffer *buffer); // custom data receiver }; @@ -72,8 +78,10 @@ protected: long notifyID; std::vector subscribers; + list sent; GenericAsyncStream *stream; + FlowSystemSender sender; bool pull; Notification pullNotification; @@ -87,6 +95,7 @@ // Port interface ASyncPort(std::string name, void *ptr, long flags, StdScheduleNode* parent); + ~ASyncPort(); void connect(Port *port); void disconnect(Port *port); Index: flow/synthschedule.cc =================================================================== RCS file: /home/kde/kdelibs/arts/flow/synthschedule.cc,v retrieving revision 1.30 diff -u -u -r1.30 synthschedule.cc --- flow/synthschedule.cc 2000/09/28 22:42:37 1.30 +++ flow/synthschedule.cc 2000/09/29 15:12:45 @@ -857,13 +857,16 @@ if(ap) { + FlowSystemSender sender; + FlowSystemReceiver receiver; + FlowSystem remoteFs; + ASyncNetSend *netsend = new ASyncNetSend(); ap->sendNet(netsend); - - FlowSystem remoteFs = destObject._flowSystem(); - FlowSystemReceiver receiver; - receiver = remoteFs.createReceiver(destObject, destPort, FlowSystemSender::_from_base(netsend)); + sender = FlowSystemSender::_from_base(netsend); // don't release netsend + remoteFs = destObject._flowSystem(); + receiver = remoteFs.createReceiver(destObject, destPort, sender); netsend->setReceiver(receiver); arts_debug("connected an asyncnetsend"); } @@ -913,7 +916,7 @@ * really disconnected on connection drop, which is also bad (but * not as ugly as a crash) */ - return FlowSystemReceiver::_from_base((new ASyncNetReceive(ap, sender))->_copy()); + return FlowSystemReceiver::_from_base(new ASyncNetReceive(ap, sender)); } return FlowSystemReceiver::null(); } @@ -958,7 +961,7 @@ if(died > 10000) { free(done); - artsdebug("scheduler confusion: circle?\n"); + arts_warning("scheduler confusion: circle?"); return; } } Index: mcop/connection.cc =================================================================== RCS file: /home/kde/kdelibs/arts/mcop/connection.cc,v retrieving revision 1.9 diff -u -u -r1.9 connection.cc --- mcop/connection.cc 2000/09/28 22:42:37 1.9 +++ mcop/connection.cc 2000/09/29 15:12:46 @@ -58,6 +58,12 @@ void Connection::receive(unsigned char *data, long len) { + /* + * protect against being freed while receive is running, as there are a + * few points where reentrant event loops may happen (Dispatcher::handle) + */ + _copy(); + if(len > remaining) { unsigned char *data2 = data+remaining; @@ -66,6 +72,8 @@ /* This could be optimized to a non recursive thing (fixme?) */ receive(data2,len2); + + _release(); // closes _copy() from start return; } // get a buffer for the incoming message: @@ -135,4 +143,5 @@ Dispatcher::the()->handle(this,received,messageType); } } + _release(); // closes _copy() from start } Index: mcop/core.cc =================================================================== RCS file: /home/kde/kdelibs/arts/mcop/core.cc,v retrieving revision 1.44 diff -u -u -r1.44 core.cc --- mcop/core.cc 2000/09/28 21:14:26 1.44 +++ mcop/core.cc 2000/09/29 15:12:58 @@ -1179,6 +1179,19 @@ } +void Arts::FlowSystemSender_stub::disconnect() +{ + long methodID = _lookupMethodFast("method:0000000b646973636f6e6e6563740000000005766f696400000000020000000000000000"); + long requestID; + Arts::Buffer *request, *result; + request = Arts::Dispatcher::the()->createRequest(requestID,_objectID,methodID); + request->patchLength(); + _connection->qSendBuffer(request); + + result = Arts::Dispatcher::the()->waitForResult(requestID,_connection); + if(result) delete result; +} + std::string Arts::FlowSystemSender_skel::_interfaceName() { return "Arts::FlowSystemSender"; @@ -1202,15 +1215,23 @@ ((Arts::FlowSystemSender_skel *)object)->processed(); } +// disconnect +static void _dispatch_Arts_FlowSystemSender_01(void *object, Arts::Buffer *, Arts::Buffer *) +{ + ((Arts::FlowSystemSender_skel *)object)->disconnect(); +} + void Arts::FlowSystemSender_skel::_buildMethodTable() { Arts::Buffer m; m.fromString( "MethodTable:0000000a70726f6365737365640000000005766f69640000000001" - "0000000000000000", + "00000000000000000000000b646973636f6e6e6563740000000005766f69640000" + "0000020000000000000000", "MethodTable" ); _addMethod(_dispatch_Arts_FlowSystemSender_00,this,Arts::MethodDef(m)); + _addMethod(_dispatch_Arts_FlowSystemSender_01,this,Arts::MethodDef(m)); } Arts::FlowSystemSender_skel::FlowSystemSender_skel() @@ -1294,6 +1315,19 @@ // constructor to create a stub for an object } +void Arts::FlowSystemReceiver_stub::disconnect() +{ + long methodID = _lookupMethodFast("method:0000000b646973636f6e6e6563740000000005766f696400000000020000000000000000"); + long requestID; + Arts::Buffer *request, *result; + request = Arts::Dispatcher::the()->createRequest(requestID,_objectID,methodID); + request->patchLength(); + _connection->qSendBuffer(request); + + result = Arts::Dispatcher::the()->waitForResult(requestID,_connection); + if(result) delete result; +} + long Arts::FlowSystemReceiver_stub::receiveHandlerID() { long methodID = _lookupMethodFast("method:000000165f6765745f7265636569766548616e646c6572494400000000056c6f6e6700000000020000000000000000"); @@ -1327,8 +1361,14 @@ return "Arts::FlowSystemReceiver"; } +// disconnect +static void _dispatch_Arts_FlowSystemReceiver_00(void *object, Arts::Buffer *, Arts::Buffer *) +{ + ((Arts::FlowSystemReceiver_skel *)object)->disconnect(); +} + // _get_receiveHandlerID -static void _dispatch_Arts_FlowSystemReceiver_00(void *object, Arts::Buffer *, Arts::Buffer *result) +static void _dispatch_Arts_FlowSystemReceiver_01(void *object, Arts::Buffer *, Arts::Buffer *result) { result->writeLong(((Arts::FlowSystemReceiver_skel *)object)->receiveHandlerID()); } @@ -1337,11 +1377,13 @@ { Arts::Buffer m; m.fromString( - "MethodTable:000000165f6765745f7265636569766548616e646c657249440000" - "0000056c6f6e6700000000020000000000000000", + "MethodTable:0000000b646973636f6e6e6563740000000005766f696400000000" + "020000000000000000000000165f6765745f7265636569766548616e646c657249" + "4400000000056c6f6e6700000000020000000000000000", "MethodTable" ); _addMethod(_dispatch_Arts_FlowSystemReceiver_00,this,Arts::MethodDef(m)); + _addMethod(_dispatch_Arts_FlowSystemReceiver_01,this,Arts::MethodDef(m)); } Arts::FlowSystemReceiver_skel::FlowSystemReceiver_skel() @@ -2386,74 +2428,76 @@ "7279547970657300000000082a737472696e6700000000020000000000000000000000" "0b7175657279456e756d7300000000082a737472696e67000000000200000000000000" "0000000000000000000000000000000017417274733a3a466c6f7753797374656d5365" - "6e6465720000000000000000010000000a70726f6365737365640000000005766f6964" - "0000000001000000000000000000000000000000000000000000000019417274733a3a" - "466c6f7753797374656d52656365697665720000000000000000000000000100000011" - "7265636569766548616e646c6572494400000000056c6f6e6700000000120000000000" - "0000000000000000000011417274733a3a466c6f7753797374656d0000000000000000" - "060000000c73746172744f626a6563740000000005766f696400000000020000000100" - "0000076f626a65637400000000056e6f64650000000000000000000000000b73746f70" - "4f626a6563740000000005766f6964000000000200000001000000076f626a65637400" - "000000056e6f64650000000000000000000000000e636f6e6e6563744f626a65637400" - "00000005766f6964000000000200000004000000076f626a656374000000000d736f75" - "7263654f626a656374000000000000000007737472696e67000000000b736f75726365" - "506f72740000000000000000076f626a656374000000000b646573744f626a65637400" - "0000000000000007737472696e67000000000964657374506f72740000000000000000" - "0000000011646973636f6e6e6563744f626a6563740000000005766f69640000000002" - "00000004000000076f626a656374000000000d736f757263654f626a65637400000000" - "0000000007737472696e67000000000b736f75726365506f7274000000000000000007" - "6f626a656374000000000b646573744f626a656374000000000000000007737472696e" - "67000000000964657374506f72740000000000000000000000000b7175657279466c61" - "67730000000014417274733a3a41747472696275746554797065000000000200000002" - "000000076f626a65637400000000056e6f6465000000000000000007737472696e6700" - "00000005706f72740000000000000000000000000f6372656174655265636569766572" - "0000000019417274733a3a466c6f7753797374656d5265636569766572000000000200" - "000003000000076f626a656374000000000b646573744f626a65637400000000000000" - "0007737472696e67000000000964657374506f7274000000000000000017417274733a" - "3a466c6f7753797374656d53656e646572000000000773656e64657200000000000000" - "000000000000000000000000000000000011417274733a3a476c6f62616c436f6d6d00" - "0000000000000003000000047075740000000008626f6f6c65616e0000000002000000" - "0200000007737472696e6700000000097661726961626c650000000000000000077374" - "72696e67000000000676616c7565000000000000000000000000046765740000000007" - "737472696e6700000000020000000100000007737472696e6700000000097661726961" - "626c650000000000000000000000000665726173650000000005766f69640000000002" - "0000000100000007737472696e6700000000097661726961626c650000000000000000" - "0000000000000000000000000000000014417274733a3a546d70476c6f62616c436f6d" - "6d000000000100000011417274733a3a476c6f62616c436f6d6d000000000000000000" - "000000000000000000000012417274733a3a5472616465724f66666572000000000000" - "0000010000000c67657450726f706572747900000000082a737472696e670000000002" - "0000000100000007737472696e6700000000056e616d65000000000000000000000000" - "010000000e696e746572666163654e616d650000000007737472696e67000000001200" - "000000000000000000000000000012417274733a3a5472616465725175657279000000" - "00000000000200000009737570706f7274730000000005766f69640000000002000000" - "0200000007737472696e67000000000970726f70657274790000000000000000077374" - "72696e67000000000676616c7565000000000000000000000000067175657279000000" - "00132a417274733a3a5472616465724f66666572000000000200000000000000000000" - "000000000000000000000000000d417274733a3a4f626a65637400000000000000000e" - "0000000e5f6c6f6f6b75704d6574686f6400000000056c6f6e67000000000200000001" - "00000010417274733a3a4d6574686f64446566000000000a6d6574686f644465660000" - "000000000000000000000f5f696e746572666163654e616d650000000007737472696e" - "6700000000020000000000000000000000105f7175657279496e746572666163650000" - "000013417274733a3a496e746572666163654465660000000002000000010000000773" - "7472696e6700000000056e616d650000000000000000000000000b5f71756572795479" - "7065000000000e417274733a3a54797065446566000000000200000001000000077374" - "72696e6700000000056e616d650000000000000000000000000b5f7175657279456e75" - "6d000000000e417274733a3a456e756d44656600000000020000000100000007737472" - "696e6700000000056e616d650000000000000000000000000a5f746f537472696e6700" - "00000007737472696e6700000000020000000000000000000000125f6973436f6d7061" - "7469626c65576974680000000008626f6f6c65616e0000000002000000010000000773" - "7472696e67000000000e696e746572666163656e616d65000000000000000000000000" - "0c5f636f707952656d6f74650000000005766f69640000000002000000000000000000" - "00000b5f75736552656d6f74650000000005766f696400000000020000000000000000" - "0000000f5f72656c6561736552656d6f74650000000005766f69640000000002000000" - "00000000000000000a5f6164644368696c640000000007737472696e67000000000200" - "000002000000076f626a65637400000000066368696c64000000000000000007737472" - "696e6700000000056e616d650000000000000000000000000d5f72656d6f7665436869" - "6c640000000008626f6f6c65616e00000000020000000100000007737472696e670000" - "0000056e616d650000000000000000000000000a5f6765744368696c6400000000076f" - "626a65637400000000020000000100000007737472696e6700000000056e616d650000" - "000000000000000000000f5f71756572794368696c6472656e00000000082a73747269" - "6e6700000000020000000000000000000000010000000c5f666c6f7753797374656d00" - "00000011417274733a3a466c6f7753797374656d000000001200000000000000000000" - "000000000000" + "6e6465720000000000000000020000000a70726f6365737365640000000005766f6964" + "000000000100000000000000000000000b646973636f6e6e6563740000000005766f69" + "640000000002000000000000000000000000000000000000000000000019417274733a" + "3a466c6f7753797374656d52656365697665720000000000000000010000000b646973" + "636f6e6e6563740000000005766f696400000000020000000000000000000000010000" + "00117265636569766548616e646c6572494400000000056c6f6e670000000012000000" + "00000000000000000000000011417274733a3a466c6f7753797374656d000000000000" + "0000060000000c73746172744f626a6563740000000005766f69640000000002000000" + "01000000076f626a65637400000000056e6f64650000000000000000000000000b7374" + "6f704f626a6563740000000005766f6964000000000200000001000000076f626a6563" + "7400000000056e6f64650000000000000000000000000e636f6e6e6563744f626a6563" + "740000000005766f6964000000000200000004000000076f626a656374000000000d73" + "6f757263654f626a656374000000000000000007737472696e67000000000b736f7572" + "6365506f72740000000000000000076f626a656374000000000b646573744f626a6563" + "74000000000000000007737472696e67000000000964657374506f7274000000000000" + "00000000000011646973636f6e6e6563744f626a6563740000000005766f6964000000" + "000200000004000000076f626a656374000000000d736f757263654f626a6563740000" + "00000000000007737472696e67000000000b736f75726365506f727400000000000000" + "00076f626a656374000000000b646573744f626a656374000000000000000007737472" + "696e67000000000964657374506f72740000000000000000000000000b717565727946" + "6c6167730000000014417274733a3a4174747269627574655479706500000000020000" + "0002000000076f626a65637400000000056e6f6465000000000000000007737472696e" + "670000000005706f72740000000000000000000000000f637265617465526563656976" + "65720000000019417274733a3a466c6f7753797374656d526563656976657200000000" + "0200000003000000076f626a656374000000000b646573744f626a6563740000000000" + "00000007737472696e67000000000964657374506f7274000000000000000017417274" + "733a3a466c6f7753797374656d53656e646572000000000773656e6465720000000000" + "0000000000000000000000000000000000000011417274733a3a476c6f62616c436f6d" + "6d000000000000000003000000047075740000000008626f6f6c65616e000000000200" + "00000200000007737472696e6700000000097661726961626c65000000000000000007" + "737472696e67000000000676616c756500000000000000000000000004676574000000" + "0007737472696e6700000000020000000100000007737472696e670000000009766172" + "6961626c650000000000000000000000000665726173650000000005766f6964000000" + "00020000000100000007737472696e6700000000097661726961626c65000000000000" + "00000000000000000000000000000000000014417274733a3a546d70476c6f62616c43" + "6f6d6d000000000100000011417274733a3a476c6f62616c436f6d6d00000000000000" + "0000000000000000000000000012417274733a3a5472616465724f6666657200000000" + "00000000010000000c67657450726f706572747900000000082a737472696e67000000" + "00020000000100000007737472696e6700000000056e616d6500000000000000000000" + "0000010000000e696e746572666163654e616d650000000007737472696e6700000000" + "1200000000000000000000000000000012417274733a3a547261646572517565727900" + "000000000000000200000009737570706f7274730000000005766f6964000000000200" + "00000200000007737472696e67000000000970726f7065727479000000000000000007" + "737472696e67000000000676616c756500000000000000000000000006717565727900" + "000000132a417274733a3a5472616465724f6666657200000000020000000000000000" + "0000000000000000000000000000000d417274733a3a4f626a65637400000000000000" + "000e0000000e5f6c6f6f6b75704d6574686f6400000000056c6f6e6700000000020000" + "000100000010417274733a3a4d6574686f64446566000000000a6d6574686f64446566" + "0000000000000000000000000f5f696e746572666163654e616d650000000007737472" + "696e6700000000020000000000000000000000105f7175657279496e74657266616365" + "0000000013417274733a3a496e74657266616365446566000000000200000001000000" + "07737472696e6700000000056e616d650000000000000000000000000b5f7175657279" + "54797065000000000e417274733a3a5479706544656600000000020000000100000007" + "737472696e6700000000056e616d650000000000000000000000000b5f717565727945" + "6e756d000000000e417274733a3a456e756d4465660000000002000000010000000773" + "7472696e6700000000056e616d650000000000000000000000000a5f746f537472696e" + "670000000007737472696e6700000000020000000000000000000000125f6973436f6d" + "70617469626c65576974680000000008626f6f6c65616e000000000200000001000000" + "07737472696e67000000000e696e746572666163656e616d6500000000000000000000" + "00000c5f636f707952656d6f74650000000005766f6964000000000200000000000000" + "000000000b5f75736552656d6f74650000000005766f69640000000002000000000000" + "00000000000f5f72656c6561736552656d6f74650000000005766f6964000000000200" + "000000000000000000000a5f6164644368696c640000000007737472696e6700000000" + "0200000002000000076f626a65637400000000066368696c6400000000000000000773" + "7472696e6700000000056e616d650000000000000000000000000d5f72656d6f766543" + "68696c640000000008626f6f6c65616e00000000020000000100000007737472696e67" + "00000000056e616d650000000000000000000000000a5f6765744368696c6400000000" + "076f626a65637400000000020000000100000007737472696e6700000000056e616d65" + "0000000000000000000000000f5f71756572794368696c6472656e00000000082a7374" + "72696e6700000000020000000000000000000000010000000c5f666c6f775379737465" + "6d0000000011417274733a3a466c6f7753797374656d00000000120000000000000000" + "0000000000000000" ); Index: mcop/core.h =================================================================== RCS file: /home/kde/kdelibs/arts/mcop/core.h,v retrieving revision 1.48 diff -u -u -r1.48 core.h --- mcop/core.h 2000/09/08 21:30:22 1.48 +++ mcop/core.h 2000/09/29 15:13:04 @@ -418,6 +418,7 @@ void *_cast(unsigned long iid); virtual void processed() = 0; + virtual void disconnect() = 0; }; class FlowSystemSender_stub : virtual public FlowSystemSender_base, virtual public Arts::Object_stub { @@ -428,6 +429,7 @@ FlowSystemSender_stub(Arts::Connection *connection, long objectID); void processed(); + void disconnect(); }; class FlowSystemSender_skel : virtual public FlowSystemSender_base, virtual public Arts::Object_skel { @@ -485,6 +487,7 @@ inline FlowSystemSender_base* _base() {return _cache?_cache:_method_call();} inline void processed(); + inline void disconnect(); }; class FlowSystemReceiver_base : virtual public Arts::Object_base { @@ -507,6 +510,7 @@ void *_cast(unsigned long iid); virtual long receiveHandlerID() = 0; + virtual void disconnect() = 0; }; class FlowSystemReceiver_stub : virtual public FlowSystemReceiver_base, virtual public Arts::Object_stub { @@ -517,6 +521,7 @@ FlowSystemReceiver_stub(Arts::Connection *connection, long objectID); long receiveHandlerID(); + void disconnect(); }; class FlowSystemReceiver_skel : virtual public FlowSystemReceiver_base, virtual public Arts::Object_skel { @@ -574,6 +579,7 @@ inline FlowSystemReceiver_base* _base() {return _cache?_cache:_method_call();} inline long receiveHandlerID(); + inline void disconnect(); }; class FlowSystem_base : virtual public Arts::Object_base { @@ -1101,9 +1107,19 @@ _cache?static_cast(_cache)->processed():static_cast(_method_call())->processed(); } +inline void Arts::FlowSystemSender::disconnect() +{ + _cache?static_cast(_cache)->disconnect():static_cast(_method_call())->disconnect(); +} + inline long Arts::FlowSystemReceiver::receiveHandlerID() { return _cache?static_cast(_cache)->receiveHandlerID():static_cast(_method_call())->receiveHandlerID(); +} + +inline void Arts::FlowSystemReceiver::disconnect() +{ + _cache?static_cast(_cache)->disconnect():static_cast(_method_call())->disconnect(); } inline void Arts::FlowSystem::startObject(Arts::Object node) Index: mcop/core.idl =================================================================== RCS file: /home/kde/kdelibs/arts/mcop/core.idl,v retrieving revision 1.28 diff -u -u -r1.28 core.idl --- mcop/core.idl 2000/08/11 13:40:43 1.28 +++ mcop/core.idl 2000/09/29 15:13:06 @@ -371,6 +371,13 @@ * a packet of the stream */ oneway void processed(); + + /** + * This method is for telling the local FlowSystemSender to break the + * connection to the remote Receiver (it's not intended to be called + * remotely) + */ + void disconnect(); }; /** @@ -384,6 +391,13 @@ * The custom message ID which should be used to send the stream packets */ readonly attribute long receiveHandlerID; + + /** + * This method is for telling the local FlowSystemReceiver to break the + * connection to the remote Sender (it's not intended to be called + * remotely) + */ + void disconnect(); }; /** @@ -408,7 +422,7 @@ */ void stopObject(object node); - /** +/** * This connects two objects, maybe even remote * * it is important that Index: mcop/datapacket.h =================================================================== RCS file: /home/kde/kdelibs/arts/mcop/datapacket.h,v retrieving revision 1.8 diff -u -u -r1.8 datapacket.h --- mcop/datapacket.h 2000/07/27 14:09:10 1.8 +++ mcop/datapacket.h 2000/09/29 15:13:07 @@ -106,7 +106,13 @@ inline void processed() { useCount--; - if(useCount == 0) channel->processedPacket(this); + if(useCount == 0) + { + if(channel) + channel->processedPacket(this); + else + delete this; + } } virtual ~GenericDataPacket() Index: mcop/dispatcher.cc =================================================================== RCS file: /home/kde/kdelibs/arts/mcop/dispatcher.cc,v retrieving revision 1.41 diff -u -u -r1.41 dispatcher.cc --- mcop/dispatcher.cc 2000/09/28 22:42:37 1.41 +++ mcop/dispatcher.cc 2000/09/29 15:13:10 @@ -182,6 +182,10 @@ if(objectManager) objectManager->removeGlobalReferences(); + /* remove everything that might have been tagged for remote copying */ + referenceClean->forceClean(); + delete referenceClean; + d->globalComm = GlobalComm::null(); /* all objects should be gone now - remove all extensions we loaded */ @@ -203,7 +207,6 @@ */ signal(SIGPIPE,orig_sigpipe); - delete referenceClean; d->interfaceRepo = InterfaceRepo::null(); @@ -389,6 +392,7 @@ long requestID = buffer->readLong(); Buffer *result = new Buffer; + // write mcop header record result->writeLong(MCOP_MAGIC); result->writeLong(0); // message length - to be patched later @@ -482,7 +486,6 @@ } else if(md5authSupported) { - Buffer *helloBuffer = new Buffer; Header header(MCOP_MAGIC,0,mcopClientHello); @@ -548,6 +551,7 @@ } Buffer *helloBuffer = new Buffer; + Header header(MCOP_MAGIC,0,mcopAuthAccept); header.writeType(*helloBuffer); d->accept->writeType(*helloBuffer); @@ -729,7 +733,7 @@ assert(conn->isConnected(reference.serverID)); return conn; } - printf("bad luck: connecting server didn't work\n"); + arts_debug("bad luck: connecting server didn't work"); // well - bad luck (connecting that server failed) conn->_release(); Index: mcop/referenceclean.cc =================================================================== RCS file: /home/kde/kdelibs/arts/mcop/referenceclean.cc,v retrieving revision 1.6 diff -u -u -r1.6 referenceclean.cc --- mcop/referenceclean.cc 2000/05/28 18:16:03 1.6 +++ mcop/referenceclean.cc 2000/09/29 15:13:10 @@ -57,6 +57,22 @@ } } +// FIXME: this might not be clean, as deleting some objects might cause +// others to go away this serial cleaning might result in bad surprises +void ReferenceClean::forceClean() +{ + /* + * and as we're giving a second chance on reference clean, we need to + * clean twice to really really clean up + */ + for(int count = 0; count < 2; count++) + { + list items = objectPool.enumerate(); + list::iterator i; + for(i=items.begin();i != items.end();i++) (*i)->_referenceClean(); + } +} + ReferenceClean::~ReferenceClean() { Dispatcher::the()->ioManager()->removeTimer(this); Index: mcop/referenceclean.h =================================================================== RCS file: /home/kde/kdelibs/arts/mcop/referenceclean.h,v retrieving revision 1.3 diff -u -u -r1.3 referenceclean.h --- mcop/referenceclean.h 2000/05/17 22:48:20 1.3 +++ mcop/referenceclean.h 2000/09/29 15:13:10 @@ -32,6 +32,16 @@ Pool& objectPool; public: ReferenceClean(Pool& objectPool); + + /** + * this routine forces cleaning of all tagged remote objects + * + * it will be called on dispatcher shutdown, since after this there + * is no remote interaction anyway, it is be used to prevent memory + * leaks + */ + void forceClean(); + void notifyTime(); virtual ~ReferenceClean(); }; Index: mcop/socketconnection.cc =================================================================== RCS file: /home/kde/kdelibs/arts/mcop/socketconnection.cc,v retrieving revision 1.12 diff -u -u -r1.12 socketconnection.cc --- mcop/socketconnection.cc 2000/09/28 20:58:52 1.12 +++ mcop/socketconnection.cc 2000/09/29 15:13:11 @@ -137,6 +137,8 @@ if(n > 0) { receive(buffer,n); + // warning: the object may not exist any more here! + return; } else if(n == 0 && errno != EAGAIN) { --lrZ03NoBR/3+SXJZ-- _______________________________________________ Kde-multimedia mailing list Kde-multimedia@master.kde.org http://master.kde.org/mailman/listinfo/kde-multimedia