mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
minor map/hash table compatibility tweaks and simplify notification center
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@33210 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
e6ec8a906f
commit
ba24ce0841
17 changed files with 223 additions and 159 deletions
57
ChangeLog
57
ChangeLog
|
@ -1,3 +1,29 @@
|
|||
2011-05-31 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Headers/Foundation/NSHashTable.h:
|
||||
* Headers/Foundation/NSMapTable.h:
|
||||
* Source/Additions/GSMime.m:
|
||||
* Source/Additions/GSXML.m:
|
||||
* Source/GSAvahiNetService.m:
|
||||
* Source/NSCallBacks.m:
|
||||
* Source/NSConcreteHashTable.m:
|
||||
* Source/NSConcreteMapTable.m:
|
||||
* Source/NSConnection.m:
|
||||
* Source/NSMessagePort.m:
|
||||
* Source/NSSocketPort.m:
|
||||
* Source/NSTask.m:
|
||||
* Source/NSTimeZone.m:
|
||||
* Source/unix/GSRunLoopCtxt.m:
|
||||
* Source/win32/GSRunLoopCtxt.m:
|
||||
Update to use new NSInteger... callback names rather than NSInt...
|
||||
for compatibility with OSX
|
||||
* Source/NSNotificationCenter.m: revert/rewrite recent GC changes to
|
||||
simplify code and preprocessor conditionals and to avoid overheads
|
||||
of using a class as an observation except for GC with cland/libobc2.
|
||||
Is it really needed even then? I guess it would be if we weren't
|
||||
using the Boehm GC library, and were stuck with a GC system which
|
||||
didn't support zeroing weak pointers in unscanned memory.
|
||||
|
||||
2011-05-29 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* configure.ac: Fix broken atomic ops again.
|
||||
|
@ -5,11 +31,12 @@
|
|||
|
||||
2011-05-30 11:40 David Chisnall <theraven@gna.org>
|
||||
|
||||
* /NSData.m:
|
||||
Add a couple of __strong annotations to pointers. Any non-id pointer that
|
||||
can store GC'd memory must be __strong. Currently, this annotation is
|
||||
largely ignored, because the runtime is a lot more lax about what may
|
||||
store pointers than Apple's, but this will be tightened up in the future.
|
||||
* Source/NSData.m:
|
||||
Add a couple of __strong annotations to pointers. Any non-id pointer
|
||||
that can store GC'd memory must be __strong. Currently, this annotation
|
||||
is largely ignored, because the runtime is a lot more lax about what
|
||||
may store pointers than Apple's, but this will be tightened up in the
|
||||
future.
|
||||
|
||||
2011-05-28 Fred Kiefer <FredKiefer@gmx.de>
|
||||
|
||||
|
@ -18,9 +45,9 @@
|
|||
|
||||
2011-05-28 18:05 David Chisnall <theraven@gna.org>
|
||||
|
||||
* libs/base/trunk/Source/NSPointerArray.m:
|
||||
* Source/NSPointerArray.m:
|
||||
Make NSPointerArray insert the correct read / write barriers in GC mode.
|
||||
* libs/base/trunk/Source/NSConcretePointerFunctions.h:
|
||||
* Source/NSConcretePointerFunctions.h:
|
||||
Add some helper functions to NSConcretePointerFunctions.h that make it
|
||||
easier to do this in the other collections that need to support GC.
|
||||
|
||||
|
@ -31,9 +58,9 @@
|
|||
|
||||
2011-05-28 14:51 David Chisnall <theraven@gna.org>
|
||||
|
||||
* libs/base/trunk/Source/NSAutoreleasePool.m,
|
||||
* libs/base/trunk/Source/NSObject.m,
|
||||
* libs/base/trunk/Source/NSZone.m:
|
||||
* Source/NSAutoreleasePool.m,
|
||||
* Source/NSObject.m,
|
||||
* Source/NSZone.m:
|
||||
First pass at hybrid GC mode. This will try use retain-release mode if
|
||||
the collector is not running. Code will run in retain/release mode
|
||||
unless something compiled with -fobjc-gc-only is loaded.
|
||||
|
@ -46,7 +73,7 @@
|
|||
|
||||
2011-05-28 12:49 David Chisnall <theraven@gna.org>
|
||||
|
||||
* libs/base/trunk/Source/NSNotificationCenter.m:
|
||||
* Source/NSNotificationCenter.m:
|
||||
__weak is only allowed on ivars and globals, so we need to turn the
|
||||
Observation structure into a class.
|
||||
|
||||
|
@ -499,7 +526,7 @@
|
|||
|
||||
2011-03-17 15:02 David Chisnall <theraven@gna.org>
|
||||
|
||||
* libs/base/trunk/Source/NSObject.m: Correctly call C++
|
||||
* Source/NSObject.m: Correctly call C++
|
||||
constructors / destructors for C++ 'objects' in ObjC++ ivars.
|
||||
|
||||
2011-03-16 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
@ -850,7 +877,7 @@
|
|||
|
||||
2011-03-02 Riccardo Mottola <rm@gnu.org>
|
||||
|
||||
* base/NSNumberFormatter/basic.m:
|
||||
* base/NSNumberFormatter/basic.m:
|
||||
Add test for checking leading zeroes in fractional part.
|
||||
|
||||
2011-03-02 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
@ -1040,7 +1067,7 @@
|
|||
|
||||
2011-02-21 11:05 David Chisnall <theraven@gna.org>
|
||||
|
||||
* libs/base/trunk/Source/GSFFIInvocation.m: Some changes to method
|
||||
* Source/GSFFIInvocation.m: Some changes to method
|
||||
type lookup when forwarding. Alway use the compiler-supplied type
|
||||
information if it exists - this is guaranteed to by the correct
|
||||
type encoding for the call frame and lets us deconstruct it
|
||||
|
@ -1150,7 +1177,7 @@
|
|||
|
||||
2011-02-19 16:02 David Chisnall <theraven@gna.org>
|
||||
|
||||
* libs/base/trunk/Source/common.h: Add some macros that map some
|
||||
* Source/common.h: Add some macros that map some
|
||||
libobjc functions to their runtime-specific variants.
|
||||
This avoids the need for ugly #ifdefs everywhere (the next commit
|
||||
will try to clean up some of this mess), and lets us use the _np
|
||||
|
|
|
@ -183,7 +183,8 @@ typedef struct _NSHashTableCallBacks
|
|||
NSString *(*describe)(NSHashTable *, const void *);
|
||||
} NSHashTableCallBacks;
|
||||
|
||||
GS_EXPORT const NSHashTableCallBacks NSIntHashCallBacks;
|
||||
GS_EXPORT const NSHashTableCallBacks NSIntegerHashCallBacks;
|
||||
GS_EXPORT const NSHashTableCallBacks NSIntHashCallBacks; /*DEPRECATED*/
|
||||
GS_EXPORT const NSHashTableCallBacks NSNonOwnedPointerHashCallBacks;
|
||||
GS_EXPORT const NSHashTableCallBacks NSNonRetainedObjectHashCallBacks;
|
||||
GS_EXPORT const NSHashTableCallBacks NSObjectHashCallBacks;
|
||||
|
|
|
@ -227,13 +227,15 @@ struct _NSMapTableValueCallBacks
|
|||
#define NSNotAnIntMapKey ((const void *)0x80000000)
|
||||
#define NSNotAPointerMapKey ((const void *)0xffffffff)
|
||||
|
||||
GS_EXPORT const NSMapTableKeyCallBacks NSIntMapKeyCallBacks;
|
||||
GS_EXPORT const NSMapTableKeyCallBacks NSIntegerMapKeyCallBacks;
|
||||
GS_EXPORT const NSMapTableKeyCallBacks NSIntMapKeyCallBacks; /*DEPRECATED*/
|
||||
GS_EXPORT const NSMapTableKeyCallBacks NSNonOwnedPointerMapKeyCallBacks;
|
||||
GS_EXPORT const NSMapTableKeyCallBacks NSNonOwnedPointerOrNullMapKeyCallBacks;
|
||||
GS_EXPORT const NSMapTableKeyCallBacks NSNonRetainedObjectMapKeyCallBacks;
|
||||
GS_EXPORT const NSMapTableKeyCallBacks NSObjectMapKeyCallBacks;
|
||||
GS_EXPORT const NSMapTableKeyCallBacks NSOwnedPointerMapKeyCallBacks;
|
||||
GS_EXPORT const NSMapTableValueCallBacks NSIntMapValueCallBacks;
|
||||
GS_EXPORT const NSMapTableValueCallBacks NSIntegerMapValueCallBacks;
|
||||
GS_EXPORT const NSMapTableValueCallBacks NSIntMapValueCallBacks; /*DEPRECATED*/
|
||||
GS_EXPORT const NSMapTableValueCallBacks NSNonOwnedPointerMapValueCallBacks;
|
||||
GS_EXPORT const NSMapTableValueCallBacks NSNonRetainedObjectMapValueCallBacks;
|
||||
GS_EXPORT const NSMapTableValueCallBacks NSObjectMapValueCallBacks;
|
||||
|
|
|
@ -4341,7 +4341,7 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold,
|
|||
if (charsets == 0)
|
||||
{
|
||||
charsets = NSCreateMapTable (NSObjectMapKeyCallBacks,
|
||||
NSIntMapValueCallBacks, 0);
|
||||
NSIntegerMapValueCallBacks, 0);
|
||||
|
||||
/*
|
||||
* These mappings were obtained primarily from
|
||||
|
@ -4621,7 +4621,7 @@ appendString(NSMutableData *m, NSUInteger offset, NSUInteger fold,
|
|||
}
|
||||
if (encodings == 0)
|
||||
{
|
||||
encodings = NSCreateMapTable (NSIntMapKeyCallBacks,
|
||||
encodings = NSCreateMapTable (NSIntegerMapKeyCallBacks,
|
||||
NSObjectMapValueCallBacks, 0);
|
||||
|
||||
/* While the charset mappings above are many to one,
|
||||
|
|
|
@ -226,7 +226,7 @@ static NSMapTable *attrNames = 0;
|
|||
{
|
||||
if (cacheDone == NO)
|
||||
setupCache();
|
||||
attrNames = NSCreateMapTable(NSIntMapKeyCallBacks,
|
||||
attrNames = NSCreateMapTable(NSIntegerMapKeyCallBacks,
|
||||
NSNonRetainedObjectMapValueCallBacks, 0);
|
||||
NSMapInsert(attrNames,
|
||||
(void*)XML_ATTRIBUTE_CDATA, (void*)@"XML_ATTRIBUTE_CDATA");
|
||||
|
@ -592,7 +592,7 @@ static NSMapTable *nsNames = 0;
|
|||
{
|
||||
if (cacheDone == NO)
|
||||
setupCache();
|
||||
nsNames = NSCreateMapTable(NSIntMapKeyCallBacks,
|
||||
nsNames = NSCreateMapTable(NSIntegerMapKeyCallBacks,
|
||||
NSNonRetainedObjectMapValueCallBacks, 0);
|
||||
NSMapInsert(nsNames,
|
||||
(void*)XML_LOCAL_NAMESPACE, (void*)@"XML_LOCAL_NAMESPACE");
|
||||
|
@ -770,7 +770,7 @@ static NSMapTable *nodeNames = 0;
|
|||
{
|
||||
if (cacheDone == NO)
|
||||
setupCache();
|
||||
nodeNames = NSCreateMapTable(NSIntMapKeyCallBacks,
|
||||
nodeNames = NSCreateMapTable(NSIntegerMapKeyCallBacks,
|
||||
NSNonRetainedObjectMapValueCallBacks, 0);
|
||||
NSMapInsert(nodeNames,
|
||||
(void*)XML_ELEMENT_NODE, (void*)@"XML_ELEMENT_NODE");
|
||||
|
|
|
@ -726,8 +726,8 @@ didUpdateRecordData: (id)data
|
|||
[_info setObject: name forKey: @"name"];
|
||||
[_info setObject: [NSNumber numberWithInteger: port]
|
||||
forKey: @"port"];
|
||||
_browsers = NSCreateMapTable(NSIntMapKeyCallBacks, valueCallbacks, 10);
|
||||
_browserTimeouts = NSCreateMapTable(NSIntMapKeyCallBacks,
|
||||
_browsers = NSCreateMapTable(NSIntegerMapKeyCallBacks, valueCallbacks, 10);
|
||||
_browserTimeouts = NSCreateMapTable(NSIntegerMapKeyCallBacks,
|
||||
NSObjectMapValueCallBacks, 10);
|
||||
if (port > 0)
|
||||
{
|
||||
|
|
|
@ -38,10 +38,10 @@
|
|||
|
||||
/** For `int's **/
|
||||
|
||||
unsigned int
|
||||
NSUInteger
|
||||
_NS_int_hash(void *table, void* i)
|
||||
{
|
||||
return (unsigned)(uintptr_t)i;
|
||||
return (uintptr_t)i;
|
||||
}
|
||||
|
||||
BOOL
|
||||
|
@ -70,11 +70,11 @@ _NS_int_describe(void *table, void* i)
|
|||
|
||||
/** For owned `void *' **/
|
||||
|
||||
unsigned int
|
||||
NSUInteger
|
||||
_NS_owned_void_p_hash(void *table, void *p)
|
||||
{
|
||||
/* P may be aligned, so we need to compensate. */
|
||||
return ((unsigned)(uintptr_t)p)/4;
|
||||
return ((uintptr_t)p)/4;
|
||||
}
|
||||
|
||||
BOOL
|
||||
|
@ -105,7 +105,7 @@ _NS_owned_void_p_describe(void *table, void *p)
|
|||
|
||||
/** For non-retained Objective-C objects **/
|
||||
|
||||
unsigned int
|
||||
NSUInteger
|
||||
_NS_non_retained_id_hash(void *table, id <NSObject> o)
|
||||
{
|
||||
return [o hash];
|
||||
|
@ -137,7 +137,7 @@ _NS_non_retained_id_describe(void *table, id <NSObject> o)
|
|||
|
||||
/** For(retainable) objects **/
|
||||
|
||||
unsigned int
|
||||
NSUInteger
|
||||
_NS_id_hash(void *table, id <NSObject> o)
|
||||
{
|
||||
return [o hash];
|
||||
|
@ -172,10 +172,10 @@ _NS_id_describe(void *table, id <NSObject> o)
|
|||
|
||||
/** For(non-owned) `void *' **/
|
||||
|
||||
unsigned int
|
||||
NSUInteger
|
||||
_NS_non_owned_void_p_hash(void *table, void *p)
|
||||
{
|
||||
return ((unsigned)(uintptr_t)p)/4;
|
||||
return ((uintptr_t)p)/4;
|
||||
}
|
||||
|
||||
BOOL
|
||||
|
@ -204,10 +204,10 @@ _NS_non_owned_void_p_describe(void *table, void *p)
|
|||
|
||||
/** For pointers to structures and `int *' **/
|
||||
|
||||
unsigned int
|
||||
NSUInteger
|
||||
_NS_int_p_hash(void *table, int *p)
|
||||
{
|
||||
return ((unsigned)(uintptr_t)p)/4;
|
||||
return ((uintptr_t)p)/4;
|
||||
}
|
||||
|
||||
BOOL
|
||||
|
|
|
@ -733,6 +733,16 @@ typedef void (*NSHT_release_func_t)(NSHashTable *, void *);
|
|||
typedef NSString *(*NSHT_describe_func_t)(NSHashTable *, const void *);
|
||||
|
||||
/** For sets of pointer-sized or smaller quantities. */
|
||||
const NSHashTableCallBacks NSIntegerHashCallBacks =
|
||||
{
|
||||
(NSHT_hash_func_t) _NS_int_hash,
|
||||
(NSHT_isEqual_func_t) _NS_int_is_equal,
|
||||
(NSHT_retain_func_t) _NS_int_retain,
|
||||
(NSHT_release_func_t) _NS_int_release,
|
||||
(NSHT_describe_func_t) _NS_int_describe
|
||||
};
|
||||
|
||||
/** For backward compatibility. */
|
||||
const NSHashTableCallBacks NSIntHashCallBacks =
|
||||
{
|
||||
(NSHT_hash_func_t) _NS_int_hash,
|
||||
|
|
|
@ -1012,6 +1012,17 @@ typedef NSString *(*NSMT_describe_func_t)(NSMapTable *, const void *);
|
|||
|
||||
|
||||
/** For keys that are pointer-sized or smaller quantities. */
|
||||
const NSMapTableKeyCallBacks NSIntegerMapKeyCallBacks =
|
||||
{
|
||||
(NSMT_hash_func_t) _NS_int_hash,
|
||||
(NSMT_is_equal_func_t) _NS_int_is_equal,
|
||||
(NSMT_retain_func_t) _NS_int_retain,
|
||||
(NSMT_release_func_t) _NS_int_release,
|
||||
(NSMT_describe_func_t) _NS_int_describe,
|
||||
NSNotAnIntMapKey
|
||||
};
|
||||
|
||||
/** For backward compatibility. */
|
||||
const NSMapTableKeyCallBacks NSIntMapKeyCallBacks =
|
||||
{
|
||||
(NSMT_hash_func_t) _NS_int_hash,
|
||||
|
@ -1078,6 +1089,14 @@ const NSMapTableKeyCallBacks NSOwnedPointerMapKeyCallBacks =
|
|||
};
|
||||
|
||||
/** For values that are pointer-sized integer quantities. */
|
||||
const NSMapTableValueCallBacks NSIntegerMapValueCallBacks =
|
||||
{
|
||||
(NSMT_retain_func_t) _NS_int_retain,
|
||||
(NSMT_release_func_t) _NS_int_release,
|
||||
(NSMT_describe_func_t) _NS_int_describe
|
||||
};
|
||||
|
||||
/** For backward compatibilty. */
|
||||
const NSMapTableValueCallBacks NSIntMapValueCallBacks =
|
||||
{
|
||||
(NSMT_retain_func_t) _NS_int_retain,
|
||||
|
|
|
@ -662,7 +662,7 @@ static NSLock *cached_proxies_gate = nil;
|
|||
NSCreateHashTable(NSNonRetainedObjectHashCallBacks, 0);
|
||||
|
||||
targetToCached =
|
||||
NSCreateMapTable(NSIntMapKeyCallBacks,
|
||||
NSCreateMapTable(NSIntegerMapKeyCallBacks,
|
||||
NSObjectMapValueCallBacks, 0);
|
||||
|
||||
root_object_map =
|
||||
|
|
|
@ -1236,7 +1236,7 @@ typedef struct {
|
|||
((internal*)(port->_internal))->_name = theName;
|
||||
((internal*)(port->_internal))->_listener = -1;
|
||||
((internal*)(port->_internal))->_handles
|
||||
= NSCreateMapTable(NSIntMapKeyCallBacks,
|
||||
= NSCreateMapTable(NSIntegerMapKeyCallBacks,
|
||||
NSObjectMapValueCallBacks, 0);
|
||||
((internal*)(port->_internal))->_myLock = [GSLazyRecursiveLock new];
|
||||
port->_is_valid = YES;
|
||||
|
|
|
@ -139,26 +139,41 @@ struct NCTbl; /* Notification Center Table structure */
|
|||
* If 'next' is 0 then the observation is unused (ie it has been
|
||||
* removed from, or not yet added to any list). The end of a
|
||||
* list is marked by 'next' being set to 'ENDOBS'.
|
||||
*
|
||||
* This is normally a structure which handles memory management using a fast
|
||||
* reference count mechanism, but when built with clang for GC, a structure
|
||||
* can't hold a zeroing weak pointer to an observer so it's implemented as a
|
||||
* trivial class instead ... and gets managed by the garbage collector.
|
||||
*/
|
||||
|
||||
@interface GSObservation : NSObject
|
||||
#ifdef __OBJC_GC__
|
||||
|
||||
@interface GSObservation : NSObject
|
||||
{
|
||||
@public
|
||||
__weak id observer; /* Object to receive message. */
|
||||
SEL selector; /* Method selector. */
|
||||
IMP method; /* Method implementation. */
|
||||
GSObservation *next; /* Next item in linked list. */
|
||||
#ifndef __OBJC_GC__
|
||||
/** Retain count. This must be stored internally, because we're
|
||||
* allocating a load of these in an array, so we can't rely on the existence
|
||||
* of the header that NSAllocateObject() adds (in non-GC mode). */
|
||||
int retained;
|
||||
#endif
|
||||
struct Obs *next; /* Next item in linked list. */
|
||||
struct NCTbl *link; /* Pointer back to chunk table */
|
||||
}
|
||||
}
|
||||
@end
|
||||
@implementation GSObservation
|
||||
@end
|
||||
#define Observation GSObservation
|
||||
|
||||
typedef GSObservation Observation;
|
||||
#else
|
||||
|
||||
typedef struct Obs {
|
||||
id observer; /* Object to receive message. */
|
||||
SEL selector; /* Method selector. */
|
||||
IMP method; /* Method implementation. */
|
||||
struct Obs *next; /* Next item in linked list. */
|
||||
int retained; /* Retain count for structure. */
|
||||
struct NCTbl *link; /* Pointer back to chunk table */
|
||||
} Observation;
|
||||
|
||||
#endif
|
||||
|
||||
#define ENDOBS ((Observation*)-1)
|
||||
|
||||
|
@ -199,11 +214,34 @@ static inline BOOL doEqual(NSString* key1, NSString* key2)
|
|||
*/
|
||||
static void listFree(Observation *list);
|
||||
|
||||
#ifdef __OBJC_GC__
|
||||
|
||||
/* Observations are managed by the GC system because they need to be
|
||||
* instances of a class in order to implement weak pointer to observer.
|
||||
*/
|
||||
#define obsRetain(X)
|
||||
#define obsFree(X)
|
||||
|
||||
#else
|
||||
|
||||
/* Observations have retain/release counts managed explicitly by fast
|
||||
* function calls.
|
||||
*/
|
||||
static void obsRetain(Observation *o);
|
||||
static void obsFree(Observation *o);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#define GSI_ARRAY_TYPES 0
|
||||
#define GSI_ARRAY_TYPE Observation*
|
||||
#define GSI_ARRAY_RELEASE(A, X) [X.ext release]
|
||||
#define GSI_ARRAY_RETAIN(A, X) [X.ext retain]
|
||||
#ifdef __OBJC_GC__
|
||||
#define GSI_ARRAY_NO_RELEASE 1
|
||||
#define GSI_ARRAY_NO_RETAIN 1
|
||||
#else
|
||||
#define GSI_ARRAY_RELEASE(A, X) obsFree(X.ext)
|
||||
#define GSI_ARRAY_RETAIN(A, X) obsRetain(X.ext)
|
||||
#endif
|
||||
|
||||
#include "GNUstepBase/GSIArray.h"
|
||||
|
||||
|
@ -229,8 +267,6 @@ static GC_descr nodeDesc; // Type descriptor for map node.
|
|||
|
||||
#include "GNUstepBase/GSIMap.h"
|
||||
|
||||
@class GSLazyRecursiveLock;
|
||||
|
||||
/*
|
||||
* An NC table is used to keep track of memory allocated to store
|
||||
* Observation structures. When an Observation is removed from the
|
||||
|
@ -259,17 +295,13 @@ typedef struct NCTbl {
|
|||
GSIMapTable nameless; /* Get messages for any name. */
|
||||
GSIMapTable named; /* Getting named messages only. */
|
||||
unsigned lockCount; /* Count recursive operations. */
|
||||
GSLazyRecursiveLock *_lock; /* Lock out other threads. */
|
||||
#ifndef __OBJC_GC__
|
||||
// In GC mode, we don't bother with a memory pool for observations, we let
|
||||
// the GC manage all of this
|
||||
NSRecursiveLock *_lock; /* Lock out other threads. */
|
||||
Observation *freeList;
|
||||
Observation **chunks;
|
||||
unsigned numChunks;
|
||||
GSIMapTable cache[CACHESIZE];
|
||||
unsigned short chunkIndex;
|
||||
unsigned short cacheIndex;
|
||||
#endif
|
||||
} NCTable;
|
||||
|
||||
#define TABLE ((NCTable*)_table)
|
||||
|
@ -278,55 +310,35 @@ typedef struct NCTbl {
|
|||
#define NAMED (TABLE->named)
|
||||
#define LOCKCOUNT (TABLE->lockCount)
|
||||
|
||||
@implementation GSObservation
|
||||
// We don't need the finalize method on ObjC-GC mode, because the collector
|
||||
// will automatically delete the zeroing weak reference, and we can't compile
|
||||
// the dealloc method in this mode because we're also not creating the fields
|
||||
// that it refers to.
|
||||
#ifndef __OBJC_GC__
|
||||
- (id)retain
|
||||
static Observation *
|
||||
obsNew(NCTable *t, SEL s, IMP m, id o)
|
||||
{
|
||||
retained++;
|
||||
return self;
|
||||
}
|
||||
- (void)release
|
||||
{
|
||||
NSAssert(retained >= 0, NSInternalInconsistencyException);
|
||||
if (retained-- == 0)
|
||||
{
|
||||
#if GS_WITH_GC
|
||||
GSAssignZeroingWeakPointer((void**)&observer, 0);
|
||||
#endif
|
||||
NCTable *t = link;
|
||||
link = (NCTable*)t->freeList;
|
||||
t->freeList = self;
|
||||
}
|
||||
}
|
||||
- (void)dealloc
|
||||
{
|
||||
// Don't actually try to destroy this in response to a -dealloc message
|
||||
// (should not be sent), since memory is allocated in a pool.
|
||||
GSNOSUPERDEALLOC;
|
||||
}
|
||||
#endif
|
||||
@end
|
||||
|
||||
|
||||
static Observation *obsNew(NCTable* t)
|
||||
{
|
||||
static Class observationClass;
|
||||
static size_t observationSize;
|
||||
Observation *obs;
|
||||
|
||||
#if __OBJC_GC__
|
||||
|
||||
/* With clang GC, observations are garbage collected and we don't
|
||||
* use a cache. However, because the reference to the observer must be
|
||||
* weak, the observation has to be an instance of a class ...
|
||||
*/
|
||||
static Class observationClass;
|
||||
|
||||
if (0 == observationClass)
|
||||
{
|
||||
observationClass = [GSObservation class];
|
||||
observationSize = class_getInstanceSize(observationClass);
|
||||
}
|
||||
#if __OBJC_GC__
|
||||
return NSAllocateObject(observationClass, 0, _zone);
|
||||
obs = NSAllocateObject(observationClass, 0, _zone);
|
||||
|
||||
#else
|
||||
|
||||
/* Generally, observations are cached and we create a 'new' observation
|
||||
* by retrieving from the cache or by allocating a block of observations
|
||||
* in one go. This works nicely to both hide observations from the
|
||||
* garbage collector (when using gcc for GC) and to provide high
|
||||
* performance for situations where apps add/remove lots of observers
|
||||
* very frequently (poor design, but something which happens in the
|
||||
* real world unfortunately).
|
||||
*/
|
||||
if (t->freeList == 0)
|
||||
{
|
||||
Observation *block;
|
||||
|
@ -338,66 +350,55 @@ static Observation *obsNew(NCTable* t)
|
|||
t->numChunks++;
|
||||
|
||||
size = t->numChunks * sizeof(Observation*);
|
||||
#if GS_WITH_GC
|
||||
t->chunks = (Observation**)NSReallocateCollectable(
|
||||
t->chunks, size, NSScannedOption);
|
||||
#else
|
||||
t->chunks = (Observation**)NSZoneRealloc(NSDefaultMallocZone(),
|
||||
t->chunks, size);
|
||||
#endif
|
||||
|
||||
size = CHUNKSIZE * observationSize;
|
||||
#if GS_WITH_GC
|
||||
size = CHUNKSIZE * sizeof(Observation);
|
||||
t->chunks[t->numChunks - 1]
|
||||
= (Observation*)NSAllocateCollectable(size, 0);
|
||||
#else
|
||||
t->chunks[t->numChunks - 1]
|
||||
= (Observation*)NSZoneMalloc(NSDefaultMallocZone(), size);
|
||||
#endif
|
||||
t->chunkIndex = 0;
|
||||
}
|
||||
block = t->chunks[t->numChunks - 1];
|
||||
|
||||
t->freeList = (Observation*)((char*)block+(observationSize * t->chunkIndex));
|
||||
t->freeList = &block[t->chunkIndex];
|
||||
t->chunkIndex++;
|
||||
t->freeList->link = 0;
|
||||
}
|
||||
obs = t->freeList;
|
||||
t->freeList = (Observation*)obs->link;
|
||||
obs->link = (void*)t;
|
||||
object_setClass(obs, observationClass);
|
||||
return obs;
|
||||
obs->retained = 0;
|
||||
obs->next = 0;
|
||||
#endif
|
||||
|
||||
obs->selector = s;
|
||||
obs->method = m;
|
||||
#if GS_WITH_GC
|
||||
GSAssignZeroingWeakPointer((void**)&obs->observer, (void*)o);
|
||||
#else
|
||||
obs->observer = o;
|
||||
#endif
|
||||
|
||||
return obs;
|
||||
}
|
||||
|
||||
static GSIMapTable mapNew(NCTable *t)
|
||||
{
|
||||
#ifdef __OBJC_GC__
|
||||
GSIMapTable m =
|
||||
NSAllocateCollectable(sizeof(GSIMapTable_t), NSScannedOption);
|
||||
GSIMapInitWithZoneAndCapacity(m, 0, 2);
|
||||
return m;
|
||||
#else
|
||||
if (t->cacheIndex > 0)
|
||||
return t->cache[--t->cacheIndex];
|
||||
{
|
||||
return t->cache[--t->cacheIndex];
|
||||
}
|
||||
else
|
||||
{
|
||||
GSIMapTable m;
|
||||
|
||||
#if GS_WITH_GC
|
||||
m = NSAllocateCollectable(sizeof(GSIMapTable_t), NSScannedOption);
|
||||
#else
|
||||
m = NSZoneMalloc(_zone, sizeof(GSIMapTable_t));
|
||||
#endif
|
||||
GSIMapInitWithZoneAndCapacity(m, _zone, 2);
|
||||
return m;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void mapFree(NCTable *t, GSIMapTable m)
|
||||
{
|
||||
#ifndef __OBJC_GC__
|
||||
if (t->cacheIndex < CACHESIZE)
|
||||
{
|
||||
t->cache[t->cacheIndex++] = m;
|
||||
|
@ -407,12 +408,10 @@ static void mapFree(NCTable *t, GSIMapTable m)
|
|||
GSIMapEmptyMap(m);
|
||||
NSZoneFree(NSDefaultMallocZone(), (void*)m);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void endNCTable(NCTable *t)
|
||||
{
|
||||
#ifndef __OBJC_GC__
|
||||
unsigned i;
|
||||
GSIMapEnumerator_t e0;
|
||||
GSIMapNode n0;
|
||||
|
@ -475,7 +474,6 @@ static void endNCTable(NCTable *t)
|
|||
NSZoneFree(NSDefaultMallocZone(), t);
|
||||
|
||||
TEST_RELEASE(t->_lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
static NCTable *newNCTable(void)
|
||||
|
@ -483,9 +481,7 @@ static NCTable *newNCTable(void)
|
|||
NCTable *t;
|
||||
|
||||
t = (NCTable*)NSAllocateCollectable(sizeof(NCTable), NSScannedOption);
|
||||
#ifndef __OBJC_GC__
|
||||
t->chunkIndex = CHUNKSIZE;
|
||||
#endif
|
||||
t->wildcard = ENDOBS;
|
||||
|
||||
t->nameless = NSAllocateCollectable(sizeof(GSIMapTable_t), NSScannedOption);
|
||||
|
@ -493,7 +489,6 @@ static NCTable *newNCTable(void)
|
|||
GSIMapInitWithZoneAndCapacity(t->nameless, _zone, 16);
|
||||
GSIMapInitWithZoneAndCapacity(t->named, _zone, 128);
|
||||
|
||||
// t->_lock = [GSLazyRecursiveLock new];
|
||||
t->_lock = [NSRecursiveLock new];
|
||||
return t;
|
||||
}
|
||||
|
@ -510,6 +505,28 @@ static inline void unlockNCTable(NCTable* t)
|
|||
[t->_lock unlock];
|
||||
}
|
||||
|
||||
#ifndef __OBJC_GC__
|
||||
static void obsFree(Observation *o)
|
||||
{
|
||||
NSCAssert(o->retained >= 0, NSInternalInconsistencyException);
|
||||
if (o->retained-- == 0)
|
||||
{
|
||||
NCTable *t = o->link;
|
||||
|
||||
#if GS_WITH_GC
|
||||
GSAssignZeroingWeakPointer((void**)&o->observer, 0);
|
||||
#endif
|
||||
o->link = (NCTable*)t->freeList;
|
||||
t->freeList = o;
|
||||
}
|
||||
}
|
||||
|
||||
static void obsRetain(Observation *o)
|
||||
{
|
||||
o->retained++;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void listFree(Observation *list)
|
||||
{
|
||||
while (list != ENDOBS)
|
||||
|
@ -518,7 +535,7 @@ static void listFree(Observation *list)
|
|||
|
||||
list = o->next;
|
||||
o->next = 0;
|
||||
[o release];
|
||||
obsFree(o);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -538,7 +555,7 @@ static Observation *listPurge(Observation *list, id observer)
|
|||
{
|
||||
tmp = list->next;
|
||||
list->next = 0;
|
||||
[list release];
|
||||
obsFree(list);
|
||||
list = tmp;
|
||||
}
|
||||
if (list != ENDOBS)
|
||||
|
@ -552,7 +569,7 @@ static Observation *listPurge(Observation *list, id observer)
|
|||
|
||||
tmp->next = next->next;
|
||||
next->next = 0;
|
||||
[next release];
|
||||
obsFree(next);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -563,7 +580,6 @@ static Observation *listPurge(Observation *list, id observer)
|
|||
return list;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Utility function to remove all the observations from a particular
|
||||
* map table node that match the specified observer. If the observer
|
||||
|
@ -609,7 +625,7 @@ purgeMapNode(GSIMapTable map, GSIMapNode node, id observer)
|
|||
* purgeCollectedFromMapNode() does the same thing but also handles cleanup
|
||||
* of the map node containing the list if necessary.
|
||||
*/
|
||||
#if GS_WITH_GC || __OBJC_GC__
|
||||
#if GS_WITH_GC
|
||||
#define purgeCollected(X) listPurge(X, nil)
|
||||
static Observation*
|
||||
purgeCollectedFromMapNode(GSIMapTable map, GSIMapNode node)
|
||||
|
@ -795,18 +811,7 @@ static NSNotificationCenter *default_center = nil;
|
|||
|
||||
lockNCTable(TABLE);
|
||||
|
||||
o = obsNew(TABLE);
|
||||
o->selector = selector;
|
||||
o->method = method;
|
||||
#if GS_WITH_GC
|
||||
GSAssignZeroingWeakPointer((void**)&o->observer, (void*)observer);
|
||||
#else
|
||||
o->observer = observer;
|
||||
#endif
|
||||
#ifndef __OBJC_GC__
|
||||
o->retained = 0;
|
||||
#endif
|
||||
o->next = 0;
|
||||
o = obsNew(TABLE, selector, method, observer);
|
||||
|
||||
if (object != nil)
|
||||
{
|
||||
|
|
|
@ -1482,7 +1482,7 @@ static Class tcpPortClass;
|
|||
if (self == [NSSocketPort class])
|
||||
{
|
||||
tcpPortClass = self;
|
||||
tcpPortMap = NSCreateMapTable(NSIntMapKeyCallBacks,
|
||||
tcpPortMap = NSCreateMapTable(NSIntegerMapKeyCallBacks,
|
||||
NSNonOwnedPointerMapValueCallBacks, 0);
|
||||
|
||||
tcpPortLock = [GSLazyRecursiveLock new];
|
||||
|
@ -1579,12 +1579,12 @@ static Class tcpPortClass;
|
|||
port->listener = -1;
|
||||
port->host = RETAIN(aHost);
|
||||
port->address = [addr copy];
|
||||
port->handles = NSCreateMapTable(NSIntMapKeyCallBacks,
|
||||
port->handles = NSCreateMapTable(NSIntegerMapKeyCallBacks,
|
||||
NSObjectMapValueCallBacks, 0);
|
||||
#if defined(__MINGW__)
|
||||
port->eventListener = WSA_INVALID_EVENT;
|
||||
port->events = NSCreateMapTable(NSIntMapKeyCallBacks,
|
||||
NSIntMapValueCallBacks, 0);
|
||||
port->events = NSCreateMapTable(NSIntegerMapKeyCallBacks,
|
||||
NSIntegerMapValueCallBacks, 0);
|
||||
#endif
|
||||
port->myLock = [GSLazyRecursiveLock new];
|
||||
port->_is_valid = YES;
|
||||
|
@ -1735,7 +1735,7 @@ static Class tcpPortClass;
|
|||
* No known ports within this port number -
|
||||
* create the map table to add the new port to.
|
||||
*/
|
||||
thePorts = NSCreateMapTable(NSIntMapKeyCallBacks,
|
||||
thePorts = NSCreateMapTable(NSIntegerMapKeyCallBacks,
|
||||
NSNonOwnedPointerMapValueCallBacks, 0);
|
||||
NSMapInsert(tcpPortMap,
|
||||
(void*)(uintptr_t)number, (void*)thePorts);
|
||||
|
|
|
@ -281,7 +281,7 @@ pty_slave(const char* name)
|
|||
* t2: complete notification ... attempt to release task object
|
||||
* but it's already deallocated.
|
||||
*/
|
||||
activeTasks = NSCreateMapTable(NSIntMapKeyCallBacks,
|
||||
activeTasks = NSCreateMapTable(NSIntegerMapKeyCallBacks,
|
||||
NSObjectMapValueCallBacks, 0);
|
||||
}
|
||||
[gnustep_global_lock unlock];
|
||||
|
|
|
@ -656,7 +656,7 @@ static NSMapTable *absolutes = 0;
|
|||
{
|
||||
if (self == [GSAbsTimeZone class])
|
||||
{
|
||||
absolutes = NSCreateMapTable(NSIntMapKeyCallBacks,
|
||||
absolutes = NSCreateMapTable(NSIntegerMapKeyCallBacks,
|
||||
NSNonOwnedPointerMapValueCallBacks, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -198,11 +198,11 @@ static const NSMapTableValueCallBacks WatcherMapValueCallBacks =
|
|||
GSIArrayInitWithZoneAndCapacity(watchers, z, 8);
|
||||
GSIArrayInitWithZoneAndCapacity(_trigger, z, 8);
|
||||
|
||||
_efdMap = NSCreateMapTable (NSIntMapKeyCallBacks,
|
||||
_efdMap = NSCreateMapTable (NSIntegerMapKeyCallBacks,
|
||||
WatcherMapValueCallBacks, 0);
|
||||
_rfdMap = NSCreateMapTable (NSIntMapKeyCallBacks,
|
||||
_rfdMap = NSCreateMapTable (NSIntegerMapKeyCallBacks,
|
||||
WatcherMapValueCallBacks, 0);
|
||||
_wfdMap = NSCreateMapTable (NSIntMapKeyCallBacks,
|
||||
_wfdMap = NSCreateMapTable (NSIntegerMapKeyCallBacks,
|
||||
WatcherMapValueCallBacks, 0);
|
||||
}
|
||||
return self;
|
||||
|
|
|
@ -170,9 +170,9 @@ static const NSMapTableValueCallBacks WatcherMapValueCallBacks =
|
|||
GSIArrayInitWithZoneAndCapacity(watchers, z, 8);
|
||||
GSIArrayInitWithZoneAndCapacity(_trigger, z, 8);
|
||||
|
||||
handleMap = NSCreateMapTable(NSIntMapKeyCallBacks,
|
||||
handleMap = NSCreateMapTable(NSIntegerMapKeyCallBacks,
|
||||
WatcherMapValueCallBacks, 0);
|
||||
winMsgMap = NSCreateMapTable(NSIntMapKeyCallBacks,
|
||||
winMsgMap = NSCreateMapTable(NSIntegerMapKeyCallBacks,
|
||||
WatcherMapValueCallBacks, 0);
|
||||
}
|
||||
return self;
|
||||
|
|
Loading…
Reference in a new issue