mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
Changes from Frith-Macdonald, NSLock fixes.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@2791 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
722df94d6e
commit
fe472a3a71
20 changed files with 363 additions and 121 deletions
41
ChangeLog
41
ChangeLog
|
@ -1,6 +1,45 @@
|
|||
Thu Apr 16 13:45:00 1998 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
|
||||
* checks/client.m: enable testing of DO strucuture return.
|
||||
|
||||
* checks/server.m: fix typo in keyword
|
||||
|
||||
* src/KeyedCollection.m: ([-decodeContentsWithCoder:]) fixed a
|
||||
memory leak.
|
||||
|
||||
* src/mframe.m: Fixed a few bugs in returning structures - now works
|
||||
properly on GNU/Linux intel. Can anyone figure out how to handle
|
||||
all this stuff using autoconf?
|
||||
|
||||
Mon Apr 20 09:23:58 1998 Adam Fedor <fedor@ultra.doc.com>
|
||||
|
||||
* src/NSLock.m: Eliminate busy waiting from NSConditionLock
|
||||
* src/NSLock.h: add instance variable and rename "value" to
|
||||
support changes to NSConditionLock
|
||||
* src/NSLock.m: Raise appropriate exceptions
|
||||
* src/NSLock.m: Prevent NSLock and NSConditionLock from being
|
||||
locked recursively
|
||||
* src/NSThread.m: -sleepUntilDate: implemented
|
||||
* src/NSThread.m: remove calls to objc_get_thread_data except
|
||||
in currentThread message
|
||||
* src/BinaryCStream.m: Replace assert's with NS*Assert
|
||||
* src/CStream.m.orig: Likewise
|
||||
* src/Decoder.m: Likewise
|
||||
* src/Encoder.m: Likewise
|
||||
* src/MemoryStream.m: Likewise
|
||||
* src/RawCStream.m: Likewise
|
||||
* src/TextCStream.m: Likewise
|
||||
* src/ostream.m.orig: Likewise
|
||||
(patches from Quetzalcoatl Bradley <qbradley@csc.uvic.ca>).
|
||||
|
||||
* src/NSFileManager.h: Include pwd.h if we have it
|
||||
* configure.in: Check for pwd.h
|
||||
* configure: regenerate.
|
||||
* src/include/config.h.in: Likewise.
|
||||
|
||||
Wed Apr 15 09:54:25 1998 Adam Fedor <fedor@doc.com>
|
||||
|
||||
* src/NSFIleManager.m ([NSFileManager
|
||||
* src/NSFileManager.m ([NSFileManager
|
||||
-fileAttributesAtPath:traverseLink:]): Add NSFileOwnerAccountName.
|
||||
* src/externs.m: Add NSFileOwnerAccountName definition.
|
||||
(patch provided by Marcus Mueller <znek@object-factory.com>)
|
||||
|
|
|
@ -69,8 +69,9 @@
|
|||
@interface NSConditionLock : NSObject <NSLocking>
|
||||
{
|
||||
@private
|
||||
objc_condition_t condition;
|
||||
objc_mutex_t mutex;
|
||||
int condition;
|
||||
int condition_value;
|
||||
}
|
||||
|
||||
// Initialize lock with condition
|
||||
|
|
|
@ -66,6 +66,9 @@
|
|||
/* Define if you have the <netinet/in.h> header file. */
|
||||
#undef HAVE_NETINET_IN_H
|
||||
|
||||
/* Define if you have the <pwd.h> header file. */
|
||||
#undef HAVE_PWD_H
|
||||
|
||||
/* Define if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
|
|
|
@ -67,7 +67,8 @@
|
|||
{
|
||||
if (self == [BinaryCStream class])
|
||||
/* Make sure that we don't overrun memory when reading _C_CHARPTR. */
|
||||
assert (sizeof(unsigned) >= NUM_BYTES_STRING_LENGTH);
|
||||
NSAssert (sizeof(unsigned) >= NUM_BYTES_STRING_LENGTH,
|
||||
@"_C_CHARPTR overruns memory");
|
||||
}
|
||||
|
||||
|
||||
|
@ -131,11 +132,13 @@ static int debug_binary_coder = 0;
|
|||
at: (const void*)d
|
||||
withName: (NSString*) name
|
||||
{
|
||||
if (!type)
|
||||
[NSException raise:NSInvalidArgumentException format:@"type is NULL"];
|
||||
|
||||
/* Make sure we're not being asked to encode an "ObjC" type. */
|
||||
assert(type);
|
||||
assert(*type != '@');
|
||||
assert(*type != '^');
|
||||
assert(*type != ':');
|
||||
NSAssert(*type != '@', @"tried to encode an \"ObjC\" type");
|
||||
NSAssert(*type != '^', @"tried to encode an \"ObjC\" type");
|
||||
NSAssert(*type != ':', @"tried to encode an \"ObjC\" type");
|
||||
|
||||
if (debug_binary_coder)
|
||||
{
|
||||
|
@ -174,7 +177,7 @@ static int debug_binary_coder = 0;
|
|||
{ \
|
||||
tmp = _CONV_FUNC (- *(_TYPE*)_PTR); \
|
||||
memcpy (buffer, &tmp, sizeof(_TYPE)); \
|
||||
assert (!(buffer[0] & 0x80)); \
|
||||
NSAssert(!(buffer[0] & 0x80), @"high bit set"); \
|
||||
buffer[0] |= 0x80; \
|
||||
} \
|
||||
else \
|
||||
|
@ -203,8 +206,8 @@ static int debug_binary_coder = 0;
|
|||
char buffer[size]; \
|
||||
int read_size; \
|
||||
read_size = [stream readBytes: buffer length: size]; \
|
||||
assert (read_size == size); \
|
||||
assert (size == sizeof(_TYPE)); \
|
||||
NSAssert (read_size == size, @"expected more input"); \
|
||||
NSAssert (size == sizeof(_TYPE), @"inconsistent size");\
|
||||
*(unsigned _TYPE*)_PTR = \
|
||||
_CONV_FUNC (*(unsigned _TYPE*)buffer); \
|
||||
if (sign) \
|
||||
|
@ -219,9 +222,9 @@ static int debug_binary_coder = 0;
|
|||
int read_size; \
|
||||
int sign; \
|
||||
read_size = [stream readBytes: buffer length: size]; \
|
||||
assert (read_size == size); \
|
||||
NSAssert (read_size == size, @"expected more input"); \
|
||||
/* xxx Remove this next requirement eventually */ \
|
||||
assert (size == sizeof(_TYPE)); \
|
||||
NSAssert (size == sizeof(_TYPE), @"inconsistent size"); \
|
||||
sign = buffer[0] & 0x80; \
|
||||
buffer[0] &= ~0x80; \
|
||||
*(unsigned _TYPE*)_PTR = \
|
||||
|
@ -275,8 +278,8 @@ static int debug_binary_coder = 0;
|
|||
char buffer[size]; \
|
||||
int read_size; \
|
||||
read_size = [stream readBytes: buffer length: size]; \
|
||||
assert (read_size == size); \
|
||||
assert (size == sizeof(_TYPE)); \
|
||||
NSAssert (read_size == size, @"expected more input"); \
|
||||
NSAssert (size == sizeof(_TYPE), @"inconsistent size");\
|
||||
*(_TYPE*)_PTR = \
|
||||
_CONV_FUNC (*(_TYPE*)buffer); \
|
||||
} \
|
||||
|
@ -288,9 +291,9 @@ static int debug_binary_coder = 0;
|
|||
char buffer[size]; \
|
||||
int read_size; \
|
||||
read_size = [stream readBytes: buffer length: size]; \
|
||||
assert (read_size == size); \
|
||||
NSAssert (read_size == size, @"expected more input"); \
|
||||
/* xxx Remove this next requirement eventually */ \
|
||||
assert (size == sizeof(unsigned _TYPE)); \
|
||||
NSAssert (size == sizeof(_TYPE), @"inconsistent size"); \
|
||||
*(unsigned _TYPE*)_PTR = \
|
||||
_CONV_FUNC (*(unsigned _TYPE*)buffer); \
|
||||
}
|
||||
|
@ -364,7 +367,8 @@ static int debug_binary_coder = 0;
|
|||
/* Get the mantissa. */
|
||||
value *= FLOAT_FACTOR;
|
||||
mantissa = value;
|
||||
assert (value - mantissa == 0);
|
||||
NSAssert (value - mantissa == 0,
|
||||
@"mantissa and value should be the same");
|
||||
/* Encode the value as its two integer components. */
|
||||
WRITE_SIGNED_TYPE (&exponent_encoded, short, htons);
|
||||
WRITE_SIGNED_TYPE (&mantissa, int, htonl);
|
||||
|
@ -388,7 +392,8 @@ static int debug_binary_coder = 0;
|
|||
value -= mantissa1;
|
||||
value *= FLOAT_FACTOR;
|
||||
mantissa2 = value;
|
||||
assert (value - mantissa2 == 0);
|
||||
NSAssert (value - mantissa2 == 0,
|
||||
@"mantissa2 and value should be the same");
|
||||
/* Encode the value as its three integer components. */
|
||||
WRITE_SIGNED_TYPE (&exponent_encoded, short, htons);
|
||||
WRITE_SIGNED_TYPE (&mantissa1, int, htonl);
|
||||
|
@ -451,10 +456,12 @@ static int debug_binary_coder = 0;
|
|||
{
|
||||
char encoded_type;
|
||||
|
||||
assert(type);
|
||||
assert(*type != '@');
|
||||
assert(*type != '^');
|
||||
assert(*type != ':');
|
||||
if (!type)
|
||||
[NSException raise:NSInvalidArgumentException format:@"type is NULL"];
|
||||
|
||||
NSAssert(*type != '@', @"tried to decode an \"ObjC\" type");
|
||||
NSAssert(*type != '^', @"tried to decode an \"ObjC\" type");
|
||||
NSAssert(*type != ':', @"tried to decode an \"ObjC\" type");
|
||||
|
||||
[stream readByte: &encoded_type];
|
||||
if (encoded_type != *type
|
||||
|
@ -472,12 +479,15 @@ static int debug_binary_coder = 0;
|
|||
unsigned read_count;
|
||||
read_count = [stream readBytes: &length
|
||||
length: NUM_BYTES_STRING_LENGTH];
|
||||
assert (read_count == NUM_BYTES_STRING_LENGTH);
|
||||
NSAssert2 (read_count == NUM_BYTES_STRING_LENGTH,
|
||||
@"expected %d bytes of input, got %d",
|
||||
NUM_BYTES_STRING_LENGTH,read_count);
|
||||
length = ntohl (length);
|
||||
OBJC_MALLOC (*(char**)d, char, length+1);
|
||||
read_count = [stream readBytes: *(char**)d
|
||||
length: length];
|
||||
assert (read_count == length);
|
||||
NSAssert2 (read_count == length,
|
||||
@"expected %d bytes of input, got %d",length,read_count);
|
||||
(*(char**)d)[length] = '\0';
|
||||
/* Autorelease the newly malloc'ed pointer? Grep for (*objc_free)
|
||||
to see the places the may have to be changed
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include <gnustep/base/StdioStream.h>
|
||||
#include <gnustep/base/CoderPrivate.h> /* for SIGNATURE_FORMAT_STRING */
|
||||
#include <Foundation/NSException.h>
|
||||
#include <assert.h>
|
||||
|
||||
id CStreamSignatureMalformedException = @"CStreamSignatureMalformedException";
|
||||
id CStreamSignatureMismatchException = @"CStreamSignatureMismatchException";
|
||||
|
|
|
@ -154,7 +154,7 @@ static id dummyObject;
|
|||
|
||||
- _coderObjectAtReference: (unsigned)xref
|
||||
{
|
||||
assert (xref_2_object);
|
||||
NSParameterAssert (xref_2_object);
|
||||
return [xref_2_object objectAtIndex: xref];
|
||||
}
|
||||
|
||||
|
@ -172,7 +172,7 @@ static id dummyObject;
|
|||
|
||||
- (void) _coderPopRootObjectTable
|
||||
{
|
||||
assert (xref_2_object_root);
|
||||
NSParameterAssert (xref_2_object_root);
|
||||
if (!interconnect_stack_height)
|
||||
{
|
||||
[xref_2_object_root release];
|
||||
|
@ -197,7 +197,7 @@ static id dummyObject;
|
|||
|
||||
- _coderTopRootObjectTable
|
||||
{
|
||||
assert (xref_2_object_root);
|
||||
NSParameterAssert (xref_2_object_root);
|
||||
return xref_2_object_root;
|
||||
}
|
||||
|
||||
|
@ -226,7 +226,7 @@ static id dummyObject;
|
|||
|
||||
- (const void*) _coderConstPtrAtReference: (unsigned)xref;
|
||||
{
|
||||
assert (xref_2_const_ptr);
|
||||
NSParameterAssert (xref_2_const_ptr);
|
||||
return NSMapGet (xref_2_const_ptr, (void*)xref);
|
||||
}
|
||||
|
||||
|
@ -248,7 +248,7 @@ static id dummyObject;
|
|||
|
||||
- (void) _coderPopForwardObjectTable
|
||||
{
|
||||
assert (address_2_fref);
|
||||
NSParameterAssert (address_2_fref);
|
||||
if (!interconnect_stack_height)
|
||||
{
|
||||
NSFreeMapTable (address_2_fref);
|
||||
|
@ -258,7 +258,7 @@ static id dummyObject;
|
|||
|
||||
- (void) _coderSatisfyForwardReference: (unsigned)fref withObject: anObj
|
||||
{
|
||||
assert (address_2_fref);
|
||||
NSParameterAssert (address_2_fref);
|
||||
if (!fref_2_object)
|
||||
/* xxx Or should this be NSObjectMapValueCallBacks, so we make
|
||||
sure the object doesn't get released before we can resolve
|
||||
|
@ -266,7 +266,8 @@ static id dummyObject;
|
|||
fref_2_object = NSCreateMapTable (NSIntMapKeyCallBacks,
|
||||
NSNonOwnedPointerMapValueCallBacks, 0);
|
||||
/* There should only be one object for each fref. */
|
||||
assert (!NSMapGet (fref_2_object, (void*)fref));
|
||||
NSAssert (!NSMapGet (fref_2_object, (void*)fref),
|
||||
@"Should have only been one object for each fref");
|
||||
NSMapInsert (fref_2_object, (void*)fref, anObj);
|
||||
}
|
||||
|
||||
|
@ -275,9 +276,9 @@ static id dummyObject;
|
|||
{
|
||||
/* Register ADDR as associated with FREF; later we will put id
|
||||
associated with FREF at ADDR. */
|
||||
assert (address_2_fref);
|
||||
NSParameterAssert (address_2_fref);
|
||||
/* There should not be duplicate addresses */
|
||||
assert (!NSMapGet (address_2_fref, addr));
|
||||
NSAssert (!NSMapGet (address_2_fref, addr), @"Duplicate addresses");
|
||||
NSMapInsert (address_2_fref, addr, (void*)fref);
|
||||
}
|
||||
|
||||
|
@ -341,7 +342,8 @@ static id dummyObject;
|
|||
It won't be cleanly readable in TextCStream's. */
|
||||
[cstream decodeName: name];
|
||||
actual_count = [[cstream stream] readBytes: b length: c];
|
||||
assert (actual_count == c);
|
||||
NSAssert2 (actual_count == c,
|
||||
@"expected to read %d bytes, read %d bytes",c,actual_count);
|
||||
}
|
||||
|
||||
- (unsigned char) decodeTag
|
||||
|
@ -518,7 +520,7 @@ static id dummyObject;
|
|||
|
||||
- (void) finishDecodingInterconnectedObjects
|
||||
{
|
||||
assert (interconnect_stack_height);
|
||||
NSParameterAssert (interconnect_stack_height);
|
||||
|
||||
/* xxx This might not be the right thing to do; perhaps we should do
|
||||
this finishing up work at the end of each nested call, not just
|
||||
|
|
|
@ -67,7 +67,8 @@ my_object_is_class(id object)
|
|||
{
|
||||
/* This code has not yet been ported to machines for which
|
||||
a pointer is not the same size as an int. */
|
||||
assert(sizeof(void*) == sizeof(unsigned));
|
||||
NSAssert(sizeof(void*) == sizeof(unsigned),
|
||||
@"Pointer and int are different sizes");
|
||||
|
||||
/* Initialize some defaults. */
|
||||
default_stream_class = [MemoryStream class];
|
||||
|
@ -275,7 +276,7 @@ my_object_is_class(id object)
|
|||
NSIntMapValueCallBacks, 0);
|
||||
|
||||
xref = NSCountMapTable (const_ptr_2_xref) + 1;
|
||||
assert (! NSMapGet (const_ptr_2_xref, (void*)xref));
|
||||
NSAssert (! NSMapGet (const_ptr_2_xref, (void*)xref), @"xref already in Map");
|
||||
NSMapInsert (const_ptr_2_xref, ptr, (void*)xref);
|
||||
return xref;
|
||||
}
|
||||
|
@ -299,7 +300,7 @@ my_object_is_class(id object)
|
|||
NSCreateMapTable (NSNonOwnedPointerOrNullMapKeyCallBacks,
|
||||
NSIntMapValueCallBacks, 0);
|
||||
fref = ++fref_counter;
|
||||
assert ( ! NSMapGet (object_2_fref, anObject));
|
||||
NSAssert ( ! NSMapGet (object_2_fref, anObject), @"anObject already in Map");
|
||||
NSMapInsert (object_2_fref, anObject, (void*)fref);
|
||||
return fref;
|
||||
}
|
||||
|
@ -434,8 +435,8 @@ my_object_is_class(id object)
|
|||
/* It hasn't been encoded before; encode it. */
|
||||
int class_version = class_get_version (aClass);
|
||||
|
||||
assert (class_name);
|
||||
assert (*class_name);
|
||||
NSAssert (class_name, @"Class doesn't have a name");
|
||||
NSAssert (*class_name, @"Class name is empty");
|
||||
|
||||
[self encodeTag: CODER_CLASS];
|
||||
[self encodeValueOfCType: @encode(char*)
|
||||
|
@ -560,7 +561,7 @@ my_object_is_class(id object)
|
|||
encode here any forward-referenced objects that haven't been
|
||||
encoded yet. No---the current behavior implements NeXT's
|
||||
-encodeConditionalObject: */
|
||||
assert (interconnect_stack_height);
|
||||
NSParameterAssert (interconnect_stack_height);
|
||||
interconnect_stack_height--;
|
||||
}
|
||||
|
||||
|
|
|
@ -215,6 +215,11 @@
|
|||
withName: NULL];
|
||||
}
|
||||
[self initWithObjects: objs forKeys: keys count: count];
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
[keys[i] release];
|
||||
[objs[i] release];
|
||||
}
|
||||
OBJC_FREE(objs);
|
||||
OBJC_FREE(keys);
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include <Foundation/NSData.h>
|
||||
#include <Foundation/NSException.h>
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* Deal with memchr: */
|
||||
#if STDC_HEADERS || HAVE_STRING_H
|
||||
|
@ -314,7 +313,7 @@ void unchar_func(void *s, int c)
|
|||
As per above kludge, this would happen if we happen to have more than
|
||||
128 bytes left in the buffer and we try to write a string longer than
|
||||
the num bytes left in the buffer. */
|
||||
assert(prefix + position <= [data capacity]);
|
||||
NSAssert(prefix + position <= [data capacity], @"buffer overrun");
|
||||
if (position > eof_position)
|
||||
eof_position = position;
|
||||
[data setLength:eof_position + prefix];
|
||||
|
|
|
@ -106,7 +106,9 @@
|
|||
#endif
|
||||
|
||||
#include <fcntl.h>
|
||||
|
||||
#if HAVE_PWD_H
|
||||
#include <pwd.h> /* For struct passwd */
|
||||
#endif
|
||||
#if HAVE_UTIME_H
|
||||
# include <utime.h>
|
||||
#endif
|
||||
|
@ -600,7 +602,9 @@ static NSFileManager* defaultManager = nil;
|
|||
{
|
||||
struct stat statbuf;
|
||||
const char* cpath = [self fileSystemRepresentationWithPath:path];
|
||||
#if HAVE_PWD_H
|
||||
struct passwd *pw;
|
||||
#endif
|
||||
int mode;
|
||||
int count = 10;
|
||||
|
||||
|
@ -652,7 +656,7 @@ static NSFileManager* defaultManager = nil;
|
|||
#endif
|
||||
else
|
||||
values[8] = NSFileTypeUnknown;
|
||||
|
||||
#if HAVE_PWD_H
|
||||
pw = getpwuid(statbuf.st_uid);
|
||||
|
||||
if(pw)
|
||||
|
@ -660,6 +664,7 @@ static NSFileManager* defaultManager = nil;
|
|||
values[9] = [NSString stringWithCString:pw->pw_name];
|
||||
}
|
||||
else
|
||||
#endif /* HAVE_PWD_H */
|
||||
{
|
||||
count = 9;
|
||||
}
|
||||
|
|
217
Source/NSLock.m
217
Source/NSLock.m
|
@ -26,6 +26,36 @@
|
|||
#include <Foundation/NSLock.h>
|
||||
#include <Foundation/NSException.h>
|
||||
|
||||
// Exceptions
|
||||
|
||||
NSString *NSLockException = @"NSLockException";
|
||||
NSString *NSConditionLockException = @"NSConditionLockException";
|
||||
NSString *NSRecursiveLockException = @"NSRecursiveLockException";
|
||||
|
||||
// Macros
|
||||
|
||||
#define CHECK_RECURSIVE_LOCK(mutex) \
|
||||
{ \
|
||||
if ((mutex)->owner == objc_thread_id()) \
|
||||
{ \
|
||||
[NSException \
|
||||
raise:NSLockException \
|
||||
format:@"Thread attempted to recursively lock"]; \
|
||||
/* NOT REACHED */ \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CHECK_RECURSIVE_CONDITION_LOCK(mutex) \
|
||||
{ \
|
||||
if ((mutex)->owner == objc_thread_id()) \
|
||||
{ \
|
||||
[NSException \
|
||||
raise:NSConditionLockException \
|
||||
format:@"Thread attempted to recursively lock"]; \
|
||||
/* NOT REACHED */ \
|
||||
} \
|
||||
}
|
||||
|
||||
// NSLock class
|
||||
// Simplest lock for protecting critical sections of code
|
||||
|
||||
|
@ -38,7 +68,11 @@
|
|||
|
||||
// Allocate the mutex from the runtime
|
||||
mutex = objc_mutex_allocate();
|
||||
NSParameterAssert (mutex);
|
||||
if (!mutex)
|
||||
{
|
||||
NSLog(@"Failed to allocate a mutex");
|
||||
return nil;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -46,7 +80,12 @@
|
|||
{
|
||||
// Ask the runtime to deallocate the mutex
|
||||
// If there are outstanding locks then it will block
|
||||
objc_mutex_deallocate (mutex);
|
||||
if (objc_mutex_deallocate (mutex) == -1)
|
||||
{
|
||||
[NSException raise:NSLockException
|
||||
format:@"invalid mutex"];
|
||||
/* NOT REACHED */
|
||||
}
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
@ -54,6 +93,8 @@
|
|||
// Does not block
|
||||
- (BOOL) tryLock
|
||||
{
|
||||
CHECK_RECURSIVE_LOCK (mutex);
|
||||
|
||||
// Ask the runtime to acquire a lock on the mutex
|
||||
if (objc_mutex_trylock (mutex) == -1)
|
||||
return NO;
|
||||
|
@ -64,15 +105,27 @@
|
|||
// NSLocking protocol
|
||||
- (void) lock
|
||||
{
|
||||
CHECK_RECURSIVE_LOCK (mutex);
|
||||
|
||||
// Ask the runtime to acquire a lock on the mutex
|
||||
// This will block
|
||||
objc_mutex_lock (mutex);
|
||||
if (objc_mutex_lock (mutex) == -1)
|
||||
{
|
||||
[NSException raise:NSLockException
|
||||
format:@"failed to lock mutex"];
|
||||
/* NOT REACHED */
|
||||
}
|
||||
}
|
||||
|
||||
- (void)unlock
|
||||
{
|
||||
// Ask the runtime to release a lock on the mutex
|
||||
objc_mutex_unlock (mutex);
|
||||
if (objc_mutex_unlock (mutex) == -1)
|
||||
{
|
||||
[NSException raise:NSLockException
|
||||
format:@"unlock: failed to unlock mutex"];
|
||||
/* NOT REACHED */
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -94,11 +147,21 @@
|
|||
{
|
||||
[super init];
|
||||
|
||||
condition = value;
|
||||
condition_value = value;
|
||||
|
||||
// Allocate the mutex from the runtime
|
||||
condition = objc_condition_allocate ();
|
||||
if (!condition)
|
||||
{
|
||||
NSLog(@"Failed to allocate a condition");
|
||||
return nil;
|
||||
}
|
||||
mutex = objc_mutex_allocate ();
|
||||
NSParameterAssert (mutex);
|
||||
if (!mutex)
|
||||
{
|
||||
NSLog(@"Failed to allocate a mutex");
|
||||
return nil;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -106,33 +169,49 @@
|
|||
{
|
||||
// Ask the runtime to deallocate the mutex
|
||||
// If there are outstanding locks then it will block
|
||||
objc_mutex_deallocate (mutex);
|
||||
if (objc_condition_deallocate (condition) == -1)
|
||||
{
|
||||
[NSException raise:NSConditionLockException
|
||||
format:@"dealloc: invalid condition"];
|
||||
/* NOT REACHED */
|
||||
}
|
||||
if (objc_mutex_deallocate (mutex) == -1)
|
||||
{
|
||||
[NSException raise:NSConditionLockException
|
||||
format:@"dealloc: invalid mutex"];
|
||||
/* NOT REACHED */
|
||||
}
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
// Return the current condition of the lock
|
||||
- (int)condition
|
||||
{
|
||||
return condition;
|
||||
return condition_value;
|
||||
}
|
||||
|
||||
// Acquiring and release the lock
|
||||
- (void) lockWhenCondition: (int)value
|
||||
{
|
||||
BOOL done;
|
||||
int result;
|
||||
|
||||
done = NO;
|
||||
while (!done)
|
||||
CHECK_RECURSIVE_CONDITION_LOCK (mutex);
|
||||
|
||||
if (objc_mutex_lock (mutex) == -1)
|
||||
{
|
||||
// Try to get the lock
|
||||
[self lock];
|
||||
[NSException raise:NSConditionLockException
|
||||
format:@"lockWhenCondition: failed to lock mutex"];
|
||||
/* NOT REACHED */
|
||||
}
|
||||
|
||||
// Is it in the condition we are looking for?
|
||||
if (condition == value)
|
||||
done = YES;
|
||||
else
|
||||
// Release the lock and keep waiting
|
||||
[self unlock];
|
||||
while (condition_value != value)
|
||||
{
|
||||
if (objc_condition_wait (condition,mutex) == -1)
|
||||
{
|
||||
[NSException raise:NSConditionLockException
|
||||
format:@"objc_condition_wait failed"];
|
||||
/* NOT REACHED */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,26 +220,50 @@
|
|||
int depth;
|
||||
|
||||
// First check to make sure we have the lock
|
||||
depth= objc_mutex_trylock (mutex);
|
||||
depth = objc_mutex_trylock (mutex);
|
||||
|
||||
// Another thread has the lock so abort
|
||||
if (depth == -1)
|
||||
return;
|
||||
{
|
||||
[NSException raise:NSConditionLockException
|
||||
format:@"unlockWithCondition: Tried to unlock someone else's lock"];
|
||||
/* NOT REACHED */
|
||||
}
|
||||
|
||||
// If the depth is only 1 then we just acquired
|
||||
// the lock above, bogus unlock so abort
|
||||
if (depth == 1)
|
||||
return;
|
||||
{
|
||||
[NSException raise:NSConditionLockException
|
||||
format:@"unlockWithCondition: Unlock attempted without lock"];
|
||||
/* NOT REACHED */
|
||||
}
|
||||
|
||||
// This is a valid unlock so set the condition
|
||||
condition_value = value;
|
||||
|
||||
// wake up blocked threads
|
||||
if (objc_condition_broadcast(condition) == -1)
|
||||
{
|
||||
[NSException raise:NSConditionLockException
|
||||
format:@"unlockWithCondition: objc_condition_broadcast failed"];
|
||||
/* NOT REACHED */
|
||||
}
|
||||
|
||||
// and unlock twice
|
||||
condition = value;
|
||||
objc_mutex_unlock (mutex);
|
||||
objc_mutex_unlock (mutex);
|
||||
if ((objc_mutex_unlock (mutex) == -1)
|
||||
|| (objc_mutex_unlock (mutex) == -1))
|
||||
{
|
||||
[NSException raise:NSConditionLockException
|
||||
format:@"unlockWithCondition: failed to unlock mutex"];
|
||||
/* NOT REACHED */
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL) tryLock
|
||||
{
|
||||
CHECK_RECURSIVE_CONDITION_LOCK (mutex);
|
||||
|
||||
// Ask the runtime to acquire a lock on the mutex
|
||||
if (objc_mutex_trylock(mutex) == -1)
|
||||
return NO;
|
||||
|
@ -170,12 +273,14 @@
|
|||
|
||||
- (BOOL) tryLockWhenCondition: (int)value
|
||||
{
|
||||
// tryLock message will check for recursive locks
|
||||
|
||||
// First can we even get the lock?
|
||||
if (![self tryLock])
|
||||
return NO;
|
||||
|
||||
// If we got the lock is it the right condition?
|
||||
if (condition == value)
|
||||
if (condition_value == value)
|
||||
return YES;
|
||||
else
|
||||
{
|
||||
|
@ -189,15 +294,35 @@
|
|||
// These methods ignore the condition
|
||||
- (void) lock
|
||||
{
|
||||
CHECK_RECURSIVE_CONDITION_LOCK (mutex);
|
||||
|
||||
// Ask the runtime to acquire a lock on the mutex
|
||||
// This will block
|
||||
objc_mutex_lock (mutex);
|
||||
if (objc_mutex_lock (mutex) == -1)
|
||||
{
|
||||
[NSException raise:NSConditionLockException
|
||||
format:@"lock: failed to lock mutex"];
|
||||
/* NOT REACHED */
|
||||
}
|
||||
}
|
||||
|
||||
- (void)unlock
|
||||
{
|
||||
// wake up blocked threads
|
||||
if (objc_condition_broadcast(condition) == -1)
|
||||
{
|
||||
[NSException raise:NSConditionLockException
|
||||
format:@"unlockWithCondition: objc_condition_broadcast failed"];
|
||||
/* NOT REACHED */
|
||||
}
|
||||
|
||||
// Ask the runtime to release a lock on the mutex
|
||||
objc_mutex_unlock (mutex);
|
||||
if (objc_mutex_unlock (mutex) == -1)
|
||||
{
|
||||
[NSException raise:NSConditionLockException
|
||||
format:@"unlock: failed to unlock mutex"];
|
||||
/* NOT REACHED */
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -212,21 +337,31 @@
|
|||
|
||||
@implementation NSRecursiveLock
|
||||
|
||||
// Default initializer
|
||||
// Designated initializer
|
||||
- init
|
||||
{
|
||||
[super init];
|
||||
|
||||
// Allocate the mutex from the runtime
|
||||
mutex = objc_mutex_allocate();
|
||||
NSParameterAssert (mutex);
|
||||
if (!mutex)
|
||||
{
|
||||
NSLog(@"Failed to allocate a mutex");
|
||||
return nil;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
// Ask the runtime to deallocate the mutex
|
||||
// If there are outstanding locks then it will block.
|
||||
objc_mutex_deallocate(mutex);
|
||||
// If there are outstanding locks then it will block
|
||||
if (objc_mutex_deallocate (mutex) == -1)
|
||||
{
|
||||
[NSException raise:NSRecursiveLockException
|
||||
format:@"dealloc: invalid mutex"];
|
||||
/* NOT REACHED */
|
||||
}
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
@ -246,13 +381,23 @@
|
|||
{
|
||||
// Ask the runtime to acquire a lock on the mutex
|
||||
// This will block
|
||||
objc_mutex_lock (mutex);
|
||||
if (objc_mutex_lock (mutex) == -1)
|
||||
{
|
||||
[NSException raise:NSRecursiveLockException
|
||||
format:@"lock: failed to lock mutex"];
|
||||
/* NOT REACHED */
|
||||
}
|
||||
}
|
||||
|
||||
- (void) unlock
|
||||
- (void)unlock
|
||||
{
|
||||
// Ask the runtime to release a lock onthe mutex
|
||||
objc_mutex_unlock (mutex);
|
||||
// Ask the runtime to release a lock on the mutex
|
||||
if (objc_mutex_unlock (mutex) == -1)
|
||||
{
|
||||
[NSException raise:NSRecursiveLockException
|
||||
format:@"unlock: failed to unlock mutex"];
|
||||
/* NOT REACHED */
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -116,7 +116,6 @@ static BOOL entered_multi_threaded_state;
|
|||
start-up, and for thread's created by calling
|
||||
objc_thread_detach() directly.) */
|
||||
t = [[NSThread alloc] init];
|
||||
objc_thread_set_data (t);
|
||||
return t;
|
||||
}
|
||||
|
||||
|
@ -196,9 +195,8 @@ static BOOL entered_multi_threaded_state;
|
|||
{
|
||||
NSThread *t;
|
||||
|
||||
// the the current NSThread
|
||||
t = objc_thread_get_data ();
|
||||
assert (t);
|
||||
// the current NSThread
|
||||
t = [NSThread currentThread];
|
||||
|
||||
// Post the notification
|
||||
[NotificationDispatcher
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <gnustep/base/NSString.h>
|
||||
#include <gnustep/base/StdioStream.h>
|
||||
#include <gnustep/base/TextCStream.h>
|
||||
#include <gnustep/base/NSException.h>
|
||||
|
||||
#define DEFAULT_FORMAT_VERSION 0
|
||||
|
||||
|
@ -83,10 +84,13 @@ static BOOL debug_binary_coder;
|
|||
at:d
|
||||
withName:name];
|
||||
}
|
||||
assert(type);
|
||||
assert(*type != '@');
|
||||
assert(*type != '^');
|
||||
assert(*type != ':');
|
||||
|
||||
if (!type)
|
||||
[NSException raise:NSInvalidArgumentException format:@"type is NULL"];
|
||||
|
||||
NSAssert(*type != '@', @"tried to encode an \"ObjC\" type");
|
||||
NSAssert(*type != '^', @"tried to encode an \"ObjC\" type");
|
||||
NSAssert(*type != ':', @"tried to encode an \"ObjC\" type");
|
||||
|
||||
switch (*type)
|
||||
{
|
||||
|
@ -171,10 +175,12 @@ static BOOL debug_binary_coder;
|
|||
at: (void*)d
|
||||
withName: (NSString* *)namePtr
|
||||
{
|
||||
assert(type);
|
||||
assert(*type != '@');
|
||||
assert(*type != '^');
|
||||
assert(*type != ':');
|
||||
if (!type)
|
||||
[NSException raise:NSInvalidArgumentException format:@"type is NULL"];
|
||||
|
||||
NSAssert(*type != '@', @"tried to decode an \"ObjC\" type");
|
||||
NSAssert(*type != '^', @"tried to decode an \"ObjC\" type");
|
||||
NSAssert(*type != ':', @"tried to decode an \"ObjC\" type");
|
||||
|
||||
switch (*type)
|
||||
{
|
||||
|
|
|
@ -54,10 +54,12 @@ static BOOL debug_textcoder = NO;
|
|||
at: (const void*) d
|
||||
withName: (NSString*) name;
|
||||
{
|
||||
assert(type);
|
||||
assert(*type != '@');
|
||||
assert(*type != '^');
|
||||
assert(*type != ':');
|
||||
if (!type)
|
||||
[NSException raise:NSInvalidArgumentException format:@"type is NULL"];
|
||||
|
||||
NSAssert(*type != '@', @"tried to encode an \"ObjC\" type");
|
||||
NSAssert(*type != '^', @"tried to encode an \"ObjC\" type");
|
||||
NSAssert(*type != ':', @"tried to encode an \"ObjC\" type");
|
||||
|
||||
if (!name || [name length] == 0)
|
||||
name = @"Anonymous";
|
||||
|
@ -191,11 +193,14 @@ if (debug_textcoder) \
|
|||
{
|
||||
char *tmpname;
|
||||
|
||||
assert(type);
|
||||
assert(*type != '@');
|
||||
assert(*type != '^');
|
||||
assert(*type != ':');
|
||||
assert (d);
|
||||
if (!type)
|
||||
[NSException raise:NSInvalidArgumentException format:@"type is NULL"];
|
||||
if (!d)
|
||||
[NSException raise:NSInvalidArgumentException format:@"d is NULL"];
|
||||
|
||||
NSAssert(*type != '@', @"tried to decode an \"ObjC\" type");
|
||||
NSAssert(*type != '^', @"tried to decode an \"ObjC\" type");
|
||||
NSAssert(*type != ':', @"tried to decode an \"ObjC\" type");
|
||||
|
||||
switch (*type)
|
||||
{
|
||||
|
|
|
@ -44,9 +44,15 @@
|
|||
first argument. If this is the case then all the visible arguments
|
||||
are displaced in the arg frame by the size of a pointer.
|
||||
|
||||
On GNU/Linux intel, this scheme does not apply where the structures
|
||||
are 8 bytes or smaller! I define SMALL_STRUCT_ON_STACK to the
|
||||
threshold above which the pointer needs to be placed on the stack.
|
||||
|
||||
I don't know which machines work this way, so you need to alter the
|
||||
define by hand as suits you. */
|
||||
|
||||
#define STRUCT_ADDR_ON_STACK 1
|
||||
#define SMALL_STRUCT_ON_STACK 8
|
||||
|
||||
/* Deal with strrchr: */
|
||||
#if STDC_HEADERS || HAVE_STRING_H
|
||||
|
@ -200,7 +206,10 @@ mframe_dissect_call (arglist_t argframe, const char *type,
|
|||
structures before the first real argument, we need to use an offset
|
||||
into the arg frame. */
|
||||
if (*type == _C_STRUCT_B || *type == _C_UNION_B || *type == _C_ARY_B) {
|
||||
off = sizeof(void*);
|
||||
int rsize = objc_sizeof_type(type);
|
||||
if (rsize > SMALL_STRUCT_ON_STACK) {
|
||||
off = sizeof(void*);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -472,13 +481,14 @@ mframe_do_call (const char *encoded_types,
|
|||
NSCParameterAssert (type);
|
||||
NSCParameterAssert (sel_types_match(encoded_types, type));
|
||||
|
||||
|
||||
#ifdef STRUCT_ADDR_ON_STACK
|
||||
/* On machines which pass a pointer to a location for returning
|
||||
structures before the first real argument, we need to use an offset
|
||||
into the arg frame. */
|
||||
if (*type == _C_STRUCT_B || *type == _C_UNION_B || *type == _C_ARY_B) {
|
||||
off = sizeof(void*);
|
||||
if (objc_sizeof_type(type) > SMALL_STRUCT_ON_STACK) {
|
||||
off = sizeof(void*);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -497,10 +507,11 @@ mframe_do_call (const char *encoded_types,
|
|||
else
|
||||
argframe->arg_ptr = 0;
|
||||
|
||||
/* If we are passing a pointer to return a structure in, we must allocate
|
||||
the memory for it and put it at the start of the argframe. */
|
||||
if (off)
|
||||
*(void**)argframe->arg_ptr = alloca (objc_sizeof_type(type));
|
||||
if (*type == _C_STRUCT_B || *type == _C_UNION_B || *type == _C_ARY_B) {
|
||||
/* If we are passing a pointer to return a structure in, we must allocate
|
||||
the memory for it and put it at the start of the argframe. */
|
||||
*(void**)argframe->arg_ptr = alloca(objc_sizeof_type(type));
|
||||
}
|
||||
|
||||
/* Put OBJECT and SELECTOR into the ARGFRAME. */
|
||||
|
||||
|
@ -690,11 +701,13 @@ mframe_do_call (const char *encoded_types,
|
|||
struct's that are smaller than sizeof(void*)? Are they also
|
||||
returned by reference like this? */
|
||||
/* If 'off' is non-zero, the pointer to the stored structure is at
|
||||
the start of the arg frame rather than in retframe. */
|
||||
the start of the arg frame rather than in retframe. */
|
||||
if (off)
|
||||
(*encoder) (-1, *(void**)argframe->arg_ptr, tmptype, flags);
|
||||
else
|
||||
(*encoder) (-1, *(void**)retframe, tmptype, flags);
|
||||
{
|
||||
(*encoder) (-1, *(void**)retframe, tmptype, flags);
|
||||
}
|
||||
break;
|
||||
|
||||
case _C_FLT:
|
||||
|
@ -903,7 +916,10 @@ mframe_build_return (arglist_t argframe,
|
|||
structures before the first real argument, we need to use an offset
|
||||
into the arg frame. */
|
||||
if (*rettype==_C_STRUCT_B || *rettype==_C_UNION_B || *rettype==_C_ARY_B) {
|
||||
off = sizeof(void*);
|
||||
int rsize = objc_sizeof_type(type);
|
||||
if (rsize > SMALL_STRUCT_ON_STACK) {
|
||||
off = sizeof(void*);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -964,7 +980,7 @@ mframe_build_return (arglist_t argframe,
|
|||
like this? */
|
||||
if (off)
|
||||
/* If we have been given a pointer to a location to return
|
||||
the structure in, us it. */
|
||||
the structure in, use it. */
|
||||
*(void**)retframe = *(void**)argframe->arg_ptr;
|
||||
else
|
||||
/* Allocate some memory to hold the struct or array. */
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include <gnustep/base/MemoryStream.h>
|
||||
#include <gnustep/base/StdioStream.h>
|
||||
#include <Foundation/NSString.h>
|
||||
#include <Foundation/NSException.h>
|
||||
|
||||
#define OSTREAM_EOF EOF
|
||||
|
||||
|
@ -107,7 +108,10 @@ int
|
|||
ostream_read (ostream* s, void* buf, int count)
|
||||
{
|
||||
int r = 0;
|
||||
assert(buf); /* xxxFIXME: should be an exception ? */
|
||||
|
||||
if (!buf)
|
||||
[NSException raise:NSInvalidArgumentException format:@"buf is NULL"];
|
||||
|
||||
if (s->flags & OSTREAM_READFLAG)
|
||||
r = [(id <Streaming>)s->stream_obj readBytes: buf length: count];
|
||||
if (r == 0)
|
||||
|
@ -120,7 +124,9 @@ char* ostream_gets (ostream* s, char* buf, int count)
|
|||
char r, c;
|
||||
int i = 0;
|
||||
|
||||
assert(buf); /* xxxFIXME: should be an exception ? */
|
||||
if (!buf)
|
||||
[NSException raise:NSInvalidArgumentException format:@"buf is NULL"];
|
||||
|
||||
if (!(s->flags & OSTREAM_READFLAG))
|
||||
return NULL;
|
||||
while (i < count-1) {
|
||||
|
@ -139,7 +145,9 @@ char* ostream_gets (ostream* s, char* buf, int count)
|
|||
int
|
||||
ostream_write (ostream* s, const void* buf, int count)
|
||||
{
|
||||
assert(buf); /* xxxFIXME: should be an exception ? */
|
||||
if (!buf)
|
||||
[NSException raise:NSInvalidArgumentException format:@"buf is NULL"];
|
||||
|
||||
if (s->flags & OSTREAM_WRITEFLAG)
|
||||
return [(id <Streaming>)s->stream_obj writeBytes: buf length: count];
|
||||
return OSTREAM_EOF;
|
||||
|
|
|
@ -98,7 +98,7 @@ int main(int argc, char *argv[])
|
|||
[p sendStruct:f];
|
||||
[p sendSmallStruct:small];
|
||||
[p sendStructArray:ma];
|
||||
#if 0
|
||||
#if 1
|
||||
/* returning structures isn't working yet. */
|
||||
f2 = [p returnStruct];
|
||||
printf(">>returned foo: i=%d s=%s l=%lu\n",
|
||||
|
|
|
@ -160,7 +160,7 @@
|
|||
return self;
|
||||
}
|
||||
#ifdef _F_BYREF
|
||||
- sendByref: (ref id)o
|
||||
- sendByref: (byref id)o
|
||||
{
|
||||
printf(">> byref class is %s\n", object_get_class_name (o));
|
||||
return self;
|
||||
|
|
2
configure
vendored
2
configure
vendored
|
@ -2062,7 +2062,7 @@ done
|
|||
#--------------------------------------------------------------------
|
||||
# Header files and functions for files and filesystems
|
||||
#--------------------------------------------------------------------
|
||||
for ac_hdr in sys/stat.h sys/vfs.h sys/statfs.h sys/statvfs.h
|
||||
for ac_hdr in sys/stat.h sys/vfs.h sys/statfs.h sys/statvfs.h pwd.h
|
||||
do
|
||||
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
|
||||
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
|
||||
|
|
|
@ -211,7 +211,7 @@ AC_CHECK_HEADERS(values.h)
|
|||
#--------------------------------------------------------------------
|
||||
# Header files and functions for files and filesystems
|
||||
#--------------------------------------------------------------------
|
||||
AC_CHECK_HEADERS(sys/stat.h sys/vfs.h sys/statfs.h sys/statvfs.h)
|
||||
AC_CHECK_HEADERS(sys/stat.h sys/vfs.h sys/statfs.h sys/statvfs.h pwd.h)
|
||||
AC_CHECK_FUNCS(statvfs)
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in a new issue