mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
Fix NSURLSession memory management of libdispatch objects and overrelease in GSHTTPURLProtocol.
This commit is contained in:
parent
2f5b26df06
commit
18f81f9ccc
7 changed files with 51 additions and 13 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
|||
2023-01-13 Frederik Seiffert <frederik@algoriddim.com>
|
||||
|
||||
* Source/GSEasyHandle.m:
|
||||
* Source/GSMultiHandle.m:
|
||||
* Source/GSTimeoutSource.h:
|
||||
* Source/GSTimeoutSource.m:
|
||||
* Source/NSURLSession.m:
|
||||
Fix NSURLSession memory management of libdispatch objects.
|
||||
* Source/GSHTTPURLProtocol.m:
|
||||
Fix overrelease.
|
||||
|
||||
2023-01-13 Frederik Seiffert <frederik@algoriddim.com>
|
||||
|
||||
* Headers/Foundation/NSURLSession.h:
|
||||
|
|
|
@ -195,6 +195,7 @@ curl_socket_function(void *userdata, curl_socket_t fd, curlsocktype type)
|
|||
curl_slist_free_all(_headerList);
|
||||
free(_errorBuffer);
|
||||
DESTROY(_config);
|
||||
[_timeoutTimer cancel];
|
||||
DESTROY(_timeoutTimer);
|
||||
DESTROY(_URL);
|
||||
[super dealloc];
|
||||
|
@ -217,6 +218,7 @@ curl_socket_function(void *userdata, curl_socket_t fd, curlsocktype type)
|
|||
|
||||
- (void) setTimeoutTimer: (GSTimeoutSource*)timer
|
||||
{
|
||||
[_timeoutTimer cancel];
|
||||
ASSIGN(_timeoutTimer, timer);
|
||||
}
|
||||
|
||||
|
@ -234,10 +236,15 @@ curl_socket_function(void *userdata, curl_socket_t fd, curlsocktype type)
|
|||
{
|
||||
// simply create a new timer with the same queue, timeout and handler
|
||||
// this must cancel the old handler and reset the timer
|
||||
DESTROY(_timeoutTimer);
|
||||
_timeoutTimer = [[GSTimeoutSource alloc] initWithQueue: [_timeoutTimer queue]
|
||||
milliseconds: [_timeoutTimer milliseconds]
|
||||
handler: [_timeoutTimer handler]];
|
||||
if (_timeoutTimer)
|
||||
{
|
||||
GSTimeoutSource *oldTimer = _timeoutTimer;
|
||||
[oldTimer cancel];
|
||||
_timeoutTimer = [[GSTimeoutSource alloc] initWithQueue: [oldTimer queue]
|
||||
milliseconds: [oldTimer milliseconds]
|
||||
handler: [oldTimer handler]];
|
||||
RELEASE(oldTimer);
|
||||
}
|
||||
}
|
||||
|
||||
- (void) setupCallbacks
|
||||
|
|
|
@ -592,17 +592,14 @@ parseArgumentPart(NSString *part, NSString *name)
|
|||
[hh addEntriesFromDictionary:
|
||||
[self transformLowercaseKeyForHTTPHeaders: HTTPHeaders]];
|
||||
|
||||
NSArray *curlHeaders = [self curlHeadersForHTTPHeaders: hh];
|
||||
NSMutableArray *curlHeaders = [self curlHeadersForHTTPHeaders: hh];
|
||||
if ([[request HTTPMethod] isEqualToString:@"POST"]
|
||||
&& [[request HTTPBody] length] > 0
|
||||
&& [request valueForHTTPHeaderField: @"Content-Type"] == nil)
|
||||
{
|
||||
NSMutableArray *temp = [curlHeaders mutableCopy];
|
||||
[temp addObject: @"Content-Type:application/x-www-form-urlencoded"];
|
||||
curlHeaders = temp;
|
||||
[curlHeaders addObject: @"Content-Type:application/x-www-form-urlencoded"];
|
||||
}
|
||||
[_easyHandle setCustomHeaders: curlHeaders];
|
||||
RELEASE(curlHeaders);
|
||||
|
||||
NSInteger timeoutInterval = [request timeoutInterval] * 1000;
|
||||
GSTimeoutSource *timeoutTimer;
|
||||
|
@ -874,7 +871,7 @@ parseArgumentPart(NSString *part, NSString *name)
|
|||
// expects.
|
||||
//
|
||||
// - SeeAlso: https://curl.haxx.se/libcurl/c/CURLOPT_HTTPHEADER.html
|
||||
- (NSArray*) curlHeadersForHTTPHeaders: (NSDictionary*)HTTPHeaders
|
||||
- (NSMutableArray*) curlHeadersForHTTPHeaders: (NSDictionary*)HTTPHeaders
|
||||
{
|
||||
NSMutableArray *result = [NSMutableArray array];
|
||||
NSMutableSet *names = [NSMutableSet set];
|
||||
|
@ -951,7 +948,7 @@ parseArgumentPart(NSString *part, NSString *name)
|
|||
[result addObject: [NSString stringWithFormat: @"%@:", k]];
|
||||
}
|
||||
|
||||
return AUTORELEASE([result copy]);
|
||||
return result;
|
||||
}
|
||||
|
||||
// Any header values that should be passed to libcurl
|
||||
|
|
|
@ -108,8 +108,11 @@ static int curl_timer_function(CURL *easyHandle, int timeout, void *userdata) {
|
|||
NSEnumerator *e;
|
||||
GSEasyHandle *handle;
|
||||
|
||||
[_timeoutSource cancel];
|
||||
DESTROY(_timeoutSource);
|
||||
|
||||
dispatch_release(_queue);
|
||||
|
||||
e = [_easyHandles objectEnumerator];
|
||||
while (nil != (handle = [e nextObject]))
|
||||
{
|
||||
|
@ -193,10 +196,12 @@ static int curl_timer_function(CURL *easyHandle, int timeout, void *userdata) {
|
|||
// of milliseconds.
|
||||
if (-1 == value)
|
||||
{
|
||||
[_timeoutSource cancel];
|
||||
DESTROY(_timeoutSource);
|
||||
}
|
||||
else if (0 == value)
|
||||
{
|
||||
[_timeoutSource cancel];
|
||||
DESTROY(_timeoutSource);
|
||||
dispatch_async(_queue,
|
||||
^{
|
||||
|
@ -207,6 +212,7 @@ static int curl_timer_function(CURL *easyHandle, int timeout, void *userdata) {
|
|||
{
|
||||
if (nil == _timeoutSource || value != [_timeoutSource milliseconds])
|
||||
{
|
||||
[_timeoutSource cancel];
|
||||
DESTROY(_timeoutSource);
|
||||
_timeoutSource = [[GSTimeoutSource alloc] initWithQueue: _queue
|
||||
milliseconds: value
|
||||
|
@ -438,12 +444,14 @@ static int curl_timer_function(CURL *easyHandle, int timeout, void *userdata) {
|
|||
if (_readSource)
|
||||
{
|
||||
dispatch_source_cancel(_readSource);
|
||||
dispatch_release(_readSource);
|
||||
}
|
||||
_readSource = NULL;
|
||||
|
||||
if (_writeSource)
|
||||
{
|
||||
dispatch_source_cancel(_writeSource);
|
||||
dispatch_release(_writeSource);
|
||||
}
|
||||
_writeSource = NULL;
|
||||
[super dealloc];
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
dispatch_block_t _handler;
|
||||
}
|
||||
|
||||
- (void) cancel;
|
||||
|
||||
- (NSInteger) milliseconds;
|
||||
|
||||
- (dispatch_queue_t) queue;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
if (nil != (self = [super init]))
|
||||
{
|
||||
_queue = queue;
|
||||
_handler = handler;
|
||||
_handler = Block_copy(handler);
|
||||
_milliseconds = milliseconds;
|
||||
_rawSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, _queue);
|
||||
|
||||
|
@ -26,10 +26,21 @@
|
|||
|
||||
- (void) dealloc
|
||||
{
|
||||
dispatch_source_cancel(_rawSource);
|
||||
[self cancel];
|
||||
Block_release(_handler);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) cancel
|
||||
{
|
||||
if (_rawSource)
|
||||
{
|
||||
dispatch_source_cancel(_rawSource);
|
||||
dispatch_release(_rawSource);
|
||||
_rawSource = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSInteger) milliseconds
|
||||
{
|
||||
return _milliseconds;
|
||||
|
|
|
@ -970,6 +970,7 @@ static int nextSessionIdentifier()
|
|||
DESTROY(_protocolBag);
|
||||
DESTROY(_dataCompletionHandler);
|
||||
DESTROY(_knownBody);
|
||||
dispatch_release(_workQueue);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
@ -1212,6 +1213,7 @@ static int nextSessionIdentifier()
|
|||
copy->_state = _state;
|
||||
copy->_error = [_error copyWithZone: zone];
|
||||
copy->_session = _session;
|
||||
dispatch_retain(_workQueue);
|
||||
copy->_workQueue = _workQueue;
|
||||
copy->_suspendCount = _suspendCount;
|
||||
copy->_protocolLock = [_protocolLock copy];
|
||||
|
|
Loading…
Reference in a new issue