Tuukka Norri avatar Tuukka Norri committed b9af019

Memory-related fixes
- TSInvocationRecorder won't be messaged after deallocating (fixes #18).
- Also fixed a memory leak.

Comments (0)

Files changed (9)

Framework/Sources/PGTSConnection.h

     unsigned int exceptionTable;
 
     @protected
-	PGconn* connection;
-    NSLock* connectionLock;
-    struct timeval timeout;
-    NSString* connectionString;
-    volatile ConnStatusType connectionStatus;
-    volatile BOOL messageDelegateAfterConnecting;
+	PGconn* connection;			//Deallocated in disconnect
+    PGcancel* cancelRequest;	//Deallocated in disconnect
     
-    NSFileHandle* socket;
-    NSLock* asyncConnectionLock;
-    NSLock* workerThreadLock;
-    volatile BOOL shouldContinueThread;
-    volatile BOOL threadRunning;
-    volatile BOOL failedToSendQuery;
-    PGTSConnection *mainProxy, *returningMainProxy;
-    PGTSConnection *workerProxy, *returningWorkerProxy;
+    NSFileHandle* socket;											//Deallocated in workerThreadMain
+    volatile PGTSConnection *workerProxy, *returningWorkerProxy;	//Deallocated in workerThreadMain
+	volatile PGTSConnection *mainProxy, *returningMainProxy;		//Deallocated in endWorkerThread
+	
+    PGTSDatabaseInfo* databaseInfo; //Weak
+	Class resultSetClass;			//Weak
+    id delegate;					//Weak
 
     NSNotificationCenter* postgresNotificationCenter;
     NSCountedSet* notificationCounts;
     NSMutableDictionary* notificationAssociations;
 
-    PGcancel* cancelRequest;
-    PGTSDatabaseInfo* databaseInfo;
+	NSLock* connectionLock;	
+    NSLock* asyncConnectionLock;
+    NSLock* workerThreadLock;
+	
+    NSString* connectionString;
     TSObjectTagDictionary* parameterCounts;
     NSMutableDictionary* deserializationDictionary;
-    BOOL connectsAutomatically;
+    NSString* initialCommands;
+
+	BOOL connectsAutomatically;
     BOOL reconnectsAutomatically;
     BOOL overlooksFailedQueries;
     BOOL delegateProcessesNotices;
+
+	volatile ConnStatusType connectionStatus;
+    struct timeval timeout;
+
     volatile BOOL logsQueries;
-    NSString* initialCommands;
-    Class resultSetClass;        
-    id delegate;
+	volatile BOOL shouldContinueThread;
+    volatile BOOL threadRunning;
+    volatile BOOL failedToSendQuery;
+    volatile BOOL messageDelegateAfterConnecting;
 }
 
 + (PGTSConnection *) connection;

Framework/Sources/PGTSConnection.m

 
 - (void) dealloc
 {
-    //FIXME: this method needs a check.
     [self disconnect];
     //Wait for the other thread to end
     [self endWorkerThread];
     
-    [connectionLock release];
-    
-    [workerThreadLock release];
-    [asyncConnectionLock release];
-    
-    [postgresNotificationCenter release];
+	[postgresNotificationCenter release];
     [notificationCounts release];
     [notificationAssociations release];
-    
+	
+    [connectionLock release];
+    [asyncConnectionLock release];
+    [workerThreadLock release];
+        
+    [connectionString release];
     [parameterCounts release];
-    [connectionString release];
+	[deserializationDictionary release];
     [initialCommands release];
     
     log4Debug (@"Deallocating db connection: %p", self);
  */
 - (void) endWorkerThread
 {
-    messageDelegateAfterConnecting = NO;
-    [asyncConnectionLock lock];
-    [asyncConnectionLock unlock];
-    shouldContinueThread = NO;
-    [workerProxy workerEnd];
-    [workerThreadLock lock];
-    [workerThreadLock unlock];    
+	if (YES == shouldContinueThread)
+	{
+		messageDelegateAfterConnecting = NO;
+		[asyncConnectionLock lock];
+		[asyncConnectionLock unlock];
+		[workerProxy workerEnd];
+		[workerThreadLock lock];
+		[workerThreadLock unlock];
+		
+		[mainProxy release];
+		[returningMainProxy release];
+		mainProxy = nil;
+		returningMainProxy = nil;
+	}
 }
 
 

Framework/Sources/PGTSConnectionPool.h

 // $Id$
 //
 
+@class PGTSConnectionPoolItem;
+
 #import <Foundation/Foundation.h>
 #import <PGTS/PGTSConnection.h>
 
-@class PGTSConnectionPoolItem;
-
 /* 
   TODO: make PGTSConnectionPool substitute deallocated connections 
   in various objects, if there are some available:

Framework/Sources/PGTSConnectionPool.m

 // $Id$
 //
 
+#import "PGTSConnectionPoolItem.h"
 #import "PGTSConnectionPool.h"
-#import "PGTSConnectionPoolItem.h"
 #import "PGTSFunctions.h"
 #import "PGTSDatabaseInfo.h"
 #import <Log4Cocoa/Log4Cocoa.h>

Framework/Sources/PGTSConnectionPrivate.h

 // $Id$
 //
 
+#import <PGTS/PGTSResultSet.h>
 #import <PGTS/PGTSConnection.h>
-#import <PGTS/PGTSResultSet.h>
 #import <PGTS/PGTSConnectionDelegate.h>
 
 
 - (void) raiseExceptionForMissingSelector: (SEL) aSelector;
 - (void) handleNotice: (NSString *) message;
 - (void) sendFinishedConnectingMessage: (ConnStatusType) status reconnect: (BOOL) reconnected;
-- (PGTSResultSet *) resultFromProxy: (PGTSConnection *) proxy status: (int) status;
+- (PGTSResultSet *) resultFromProxy: (volatile PGTSConnection *) proxy status: (int) status;
 - (int) sendResultsToDelegate: (int) status;
 - (void) handleFailedQuery;
 @end

Framework/Sources/PGTSConnectionPrivate.m

     }
 }
 
-- (PGTSResultSet *) resultFromProxy: (PGTSConnection *) proxy status: (int) status
+- (PGTSResultSet *) resultFromProxy: (volatile PGTSConnection *) proxy status: (int) status
 {
     PGTSResultSet* res = nil;
     if (YES == failedToSendQuery)
     id runLoopMessenger  = [TSRunloopMessenger runLoopMessengerForCurrentRunLoop];
     workerProxy          = [runLoopMessenger target: self withResult: NO];
     returningWorkerProxy = [runLoopMessenger target: self withResult: YES];
-    
+
     //Prevent the run loop from exiting immediately
     [runLoop addPort: [NSPort port] forMode: mode];
     
     [threadStartLock unlock];
     
+	NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
     while (haveInputSources && shouldContinueThread)
     {
-        NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
         haveInputSources = [runLoop runMode: mode
                                  beforeDate: [NSDate distantFuture]];
-        [pool release];
+		[pool drain];
     }
+	workerProxy = nil;
+    returningWorkerProxy = nil;
     socket = nil;
-
+	[pool release];
+	
     log4Debug (@"Worker: exiting");
-    workerProxy = nil;
-    returningWorkerProxy = nil;
     [threadPool release];    
     
     [workerThreadLock unlock];
 
 - (void) workerEnd
 {
-    //A dummy method to cause some action in the run loop.
+    //Setting the variable from the main thread isn't enough;
+	//we also need to cause some action in worker's run loop by invoking this method.
+	shouldContinueThread = NO;
     log4Debug (@"workerEnd");
 }
 

Framework/Sources/PGTSConnectionQueries.m

 // $Id$
 //
 
+#import <PGTS/PGTSConstants.h>
+#import <PGTS/PGTSResultSetPrivate.h>
 #import <PGTS/PGTSConnection.h>
-#import <PGTS/PGTSConstants.h>
 #import <PGTS/PGTSConnectionPrivate.h>
 #import <PGTS/PGTSConnectionDelegate.h>
-#import <PGTS/PGTSResultSetPrivate.h>
 #import <PGTS/PGTSAdditions.h>
 #import <PGTS/PGTSFunctions.h>
 #import <PGTS/PGTSConnectionDelegate.h>

Framework/Sources/PGTSResultSetPrivate.h

 // $Id$
 //
 
+#import <PGTS/PGTSResultSet.h>
+
 @interface PGTSResultSet (PrivateMethods)
 + (id) resultWithPGresult: (PGresult *) aResult connection: (PGTSConnection *) aConnection;
 - (id) initWithResult: (PGresult *) aResult connection: (PGTSConnection *) aConnection;

Framework/Sources/TSRunloopMessenger.m

     [super dealloc];
 }
 
-
-@end
+@end
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.