static char rcsid[] = "$Id: CJRLock.m,v 1.1 1997/04/02 18:28:22 croehrig Exp $";
/*
 *  CJRLock  -- Foundation Kit-less NSLock, NSConditionLock
 *
 *  (c) 1997 Chris Roehrig <croehrig@House.ORG>
 *
 */
#import "CJRLock.h"
#import "ThreadedApp.h"

/***************	CJRLock		***************/

extern cthread_t mainThread;


@implementation CJRLock:Object

	
- init
{
    [super init];
    mutex = mutex_alloc();
    return self;
}

- free
{
    mutex_free(mutex);
    return [super free];
}

- (void)lock
{
    if( cthread_self() != mainThread ){
	// ok to block...
	mutex_lock(mutex);
    } else {
	// Don't block main event loop; use ThreadedApp's lock
	[NXApp lock:mutex];
    }

}

- (void)unlock
{
    mutex_unlock(mutex);
    if( cthread_self() != mainThread ){
	// notify main thread that an unlock has occurred (see ThreadedApp)
	[NXApp threadDidUnlock:self];
    }
}

- (BOOL)tryLock
{
    return mutex_try_lock(mutex);
}

@end


/***************	CJRConditionLock		***************/


@implementation CJRConditionLock:Object


- initWithCondition:(int)condition
{
    [super init];
    mutex = mutex_alloc();
    cond = condition_alloc();
    data = condition;

    return self;
}

- init
{
    return [self initWithCondition:0];
}

- free
{
    condition_free(cond);
    mutex_free(mutex);
    return [super free];
}

- (void)lock
{
    if( cthread_self() != mainThread ){
	// ok to block...
	mutex_lock(mutex);
    } else {
	// Don't block main event loop; use ThreadedApp's lock
	[NXApp lock:mutex];
    }
}

- (void)unlock
{
    mutex_unlock(mutex);

    // wake up other threads waiting for the lock...
    condition_broadcast(cond);

    if( cthread_self() != mainThread ){
	// notify main thread that an unlock has occurred (see ThreadedApp)
	[NXApp threadDidUnlock:self];
    }
}

- (int)condition
{
    return data;
}

- (BOOL)tryLock
{
    return mutex_try_lock(mutex);
}

- (void)lockWhenCondition:(int)condition
{
    if( cthread_self() != mainThread ){
	// blocking is ok...
	mutex_lock(mutex);
	while( data != condition )
	    condition_wait(cond,mutex);
    } else {
	// Don't block the main thread...
	[NXApp lock:mutex whenCondition:cond withData:&data is:condition];
    }
}
    

- (BOOL)tryLockWhenCondition:(int)condition
{
    if( mutex_try_lock(mutex) ){
	if( condition==data ){
	    return YES;
	} else {
	    mutex_unlock(mutex);
	    return NO;
	}
    } else {
	return NO;
    }
}
    
- (void)unlockWithCondition:(int)condition
{
    data = condition;
    mutex_unlock(mutex);

    // wake up other threads waiting for the lock...
    condition_broadcast(cond);

    // notify (wake up) the main thread 
    if( cthread_self() != mainThread ){
	[NXApp threadDidUnlock:self];
    }


}
    
@end
