|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: /* Copyright (c) 1991 NeXT Computer, Inc. All rights reserved. ! 25: * ! 26: * NXConditionLock.m. Lock object with exported condition variable, ! 27: * user version. ! 28: * ! 29: * HISTORY ! 30: * 01-Aug-91 Doug Mitchell at NeXT ! 31: * Created. ! 32: */ ! 33: ! 34: ! 35: #import <machkit/NXLock.h> ! 36: #import <mach/cthreads.h> ! 37: ! 38: @implementation NXConditionLock ! 39: ! 40: /* ! 41: * _priv instance variable points to one of these. ! 42: */ ! 43: typedef struct { ! 44: struct mutex m; ! 45: struct condition c; ! 46: int locked; ! 47: int conditionVar; ! 48: } conditionlock_priv_t; ! 49: ! 50: - init ! 51: { ! 52: conditionlock_priv_t *priv; ! 53: ! 54: [super init]; ! 55: priv = _priv = malloc(sizeof(conditionlock_priv_t)); ! 56: mutex_init(&priv->m); ! 57: condition_init(&priv->c); ! 58: priv->locked = 0; ! 59: priv->conditionVar = 0; ! 60: return self; ! 61: } ! 62: ! 63: - initWith : (int)condition ! 64: { ! 65: conditionlock_priv_t *priv; ! 66: ! 67: [self init]; ! 68: priv = _priv; ! 69: priv->conditionVar = condition; ! 70: return self; ! 71: } ! 72: ! 73: - (int) condition ! 74: { ! 75: conditionlock_priv_t *priv = _priv; ! 76: ! 77: return priv->conditionVar; ! 78: } ! 79: ! 80: - free ! 81: { ! 82: conditionlock_priv_t *priv = _priv; ! 83: ! 84: mutex_clear(&priv->m); ! 85: condition_clear(&priv->c); ! 86: free(priv); ! 87: return [super free]; ! 88: } ! 89: ! 90: // enter critical region, regardless of conditionVar ! 91: - lock ! 92: { ! 93: conditionlock_priv_t *priv = _priv; ! 94: ! 95: mutex_lock(&priv->m); ! 96: while (priv->locked) ! 97: condition_wait(&priv->c, &priv->m); // block nicely ! 98: priv->locked = TRUE; ! 99: mutex_unlock(&priv->m); ! 100: return self; ! 101: } ! 102: ! 103: // leave critical region, regardless of conditionVar ! 104: - unlock // leave critical region, regardless of conditionVar ! 105: { ! 106: conditionlock_priv_t *priv = _priv; ! 107: ! 108: mutex_lock(&priv->m); ! 109: priv->locked = FALSE; ! 110: mutex_unlock(&priv->m); ! 111: condition_broadcast(&priv->c); // let everyone check conditionVar ! 112: return self; ! 113: } ! 114: ! 115: // enter critical section only upon condition ! 116: - lockWhen : (int)value // enter critical section only upon condition ! 117: { ! 118: conditionlock_priv_t *priv = _priv; ! 119: ! 120: mutex_lock(&priv->m); ! 121: while(priv->locked || priv->conditionVar != value) ! 122: condition_wait(&priv->c, &priv->m); ! 123: priv->locked = TRUE; ! 124: mutex_unlock(&priv->m); ! 125: return self; ! 126: } ! 127: ! 128: // leave critical section, establishing condition 'value' ! 129: - unlockWith : (int)value ! 130: { ! 131: conditionlock_priv_t *priv = _priv; ! 132: ! 133: mutex_lock(&priv->m); ! 134: priv->conditionVar = value; ! 135: priv->locked = FALSE; ! 136: mutex_unlock(&priv->m); ! 137: condition_broadcast(&priv->c); // let everyone check condition ! 138: return self; ! 139: } ! 140: ! 141: @end
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.