Fixing SimpleThreads to kill inactive threads
Fixing SimpleThreads to kill inactive threads
- Subject: Fixing SimpleThreads to kill inactive threads
- From: John Nairn <email@hidden>
- Date: Fri, 23 Aug 2002 10:25:46 -0600
I found the sample code "SimpleThreads" (see
http://developer.apple.com/samplecode/Sample_Code/Processes/SimpleThreads.
htm) to be very useful to set up client/server threads in distributed
objects. But it has a serious problem (noted in its comments) that it
does not clean up correctly. The Controller.m routine killThreads does
not stop the run loops in the threads, the autoreleased pools in the
threads are never released, and the server objects are never released.
This problem was serious for my application because it will create and
need to delete many threads. I was not able to find much in
documentation or in developer archives, but after much trial and error,
I have a method I think works. Here is my fix for those interested in
similar threading applications with distributed objects.
Plan: I eventually guessed that the problem is that there are two
NSConnections - one in the client and one in the server. The killThreads
code invalidates the client's connection but not the one in the server.
The solution was to add code to the server to invalidate its connection
when you want to kill the thread.
Change 1: Add following code to TransferServer.m (and declare in the
@protocol section of TransferServer.h). This code enumerates through all
connections in the server thread. Although only one is created in
SimpleThreads, I found there are typically 4 connections. It is not good
to invalidate them all because it causes error messages in the log
window. Instead, the code locates the NSConnection created in
connectWithPorts by looking for the one that has the rootObject set to
the server object (this was set up in connectWithPorts). When that is
found, it is invalidated and that appears to be enough to finish the
task.
- (oneway void)disconnect
{
NSArray *connectionsArray=[NSConnection allConnections];
NSEnumerator *connectionsArrayEnumerator=[connectionsArray
objectEnumerator];
NSConnection *thisConnection;
while(thisConnection=[connectionsArrayEnumerator nextObject])
{ if([thisConnection rootObject]==self)
{ [thisConnection invalidate];
break;
}
}
}
Change 2: Add line to killThreads in Controller.m
[server disconnect];
just after [freeServers removeLastObject] and (importantly) before the
connection in the client thread is invalidated.
Change 3: Delete the line [server release] in killThreads in
Controller.m.
Summary: With these changes, killThreads terminates all run loops in
inactive threads, the autorelease pools are released, and the server
objects are released. I verified all actions by adding NSLog() lines
just before the autorelease pool is released and in a new dealloc method
in the server. Invalidating the NSConnection in the server accomplished
all these tasks and thus the server release in killThreads is not needed.
----------------
John Nairn (1-801-581-3413, FAX: 1-801-581-4816)
Web page:
http://www.mse.utah.edu/~nairn
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.