1/* 2 Copyright (C) 2000-2005 SKYRIX Software AG 3 4 This file is part of SOPE. 5 6 SOPE is free software; you can redistribute it and/or modify it under 7 the terms of the GNU Lesser General Public License as published by the 8 Free Software Foundation; either version 2, or (at your option) any 9 later version. 10 11 SOPE is distributed in the hope that it will be useful, but WITHOUT ANY 12 WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 14 License for more details. 15 16 You should have received a copy of the GNU Lesser General Public 17 License along with SOPE; see the file COPYING. If not, write to the 18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 19 02111-1307, USA. 20*/ 21 22#include <NGStreams/NGLockingStream.h> 23#include "common.h" 24 25@implementation NGLockingStream 26 27+ (id)filterWithSource:(id<NGStream>)_source lock:(id<NSObject,NSLocking>)_lock { 28 return [[[self alloc] initWithSource:_source lock:_lock] autorelease]; 29} 30 31- (id)initWithSource:(id<NGStream>)_source lock:(id<NSObject,NSLocking>)_lock { 32 if ((self = [super initWithSource:_source])) { 33 if (_lock == nil) { 34 readLock = [[NSRecursiveLock allocWithZone:[self zone]] init]; 35 writeLock = [readLock retain]; 36 } 37 else { 38 readLock = [_lock retain]; 39 writeLock = [readLock retain]; 40 } 41 } 42 return self; 43} 44 45- (id)initWithSource:(id<NGStream>)_source { 46 return [self initWithSource:_source lock:nil]; 47} 48 49- (void)dealloc { 50 [self->readLock release]; 51 [self->writeLock release]; 52 [super dealloc]; 53} 54 55// primitives 56 57- (unsigned)readBytes:(void *)_buf count:(unsigned)_len { 58 volatile unsigned result = 0; 59 60 [readLock lock]; 61 62 NS_DURING { 63 result = (readBytes != NULL) 64 ? (unsigned)readBytes(source, _cmd, _buf, _len) 65 : [source readBytes:_buf count:_len]; 66 } 67 NS_HANDLER { 68 [readLock unlock]; 69 [localException raise]; 70 } 71 NS_ENDHANDLER; 72 [readLock unlock]; 73 74 return result; 75} 76 77- (unsigned)writeBytes:(const void *)_buf count:(unsigned)_len { 78 volatile unsigned result = 0; 79 80 [writeLock lock]; 81 82 NS_DURING { 83 result = (writeBytes != NULL) 84 ? (unsigned)writeBytes(source, _cmd, _buf, _len) 85 : [source writeBytes:_buf count:_len]; 86 } 87 NS_HANDLER { 88 [writeLock unlock]; 89 [localException raise]; 90 } 91 NS_ENDHANDLER; 92 [writeLock unlock]; 93 94 return result; 95} 96 97- (BOOL)flush { 98 BOOL res = NO; 99 100 [writeLock lock]; 101 102 NS_DURING { 103 res = [super flush]; 104 } 105 NS_HANDLER { 106 [writeLock unlock]; 107 [localException raise]; 108 } 109 NS_ENDHANDLER; 110 [writeLock unlock]; 111 return res; 112} 113 114- (BOOL)safeReadBytes:(void *)_buf count:(unsigned)_len { 115 BOOL res = NO; 116 117 [readLock lock]; 118 119 NS_DURING { 120 res = [super safeReadBytes:_buf count:_len]; 121 } 122 NS_HANDLER { 123 [readLock unlock]; 124 [localException raise]; 125 } 126 NS_ENDHANDLER; 127 [readLock unlock]; 128 129 return res; 130} 131 132- (BOOL)safeWriteBytes:(const void *)_buf count:(unsigned)_len { 133 BOOL res = NO; 134 135 [writeLock lock]; 136 137 NS_DURING { 138 res = [super safeWriteBytes:_buf count:_len]; 139 } 140 NS_HANDLER { 141 [writeLock unlock]; 142 [localException raise]; 143 } 144 NS_ENDHANDLER; 145 [writeLock unlock]; 146 return res; 147} 148 149@end /* NGLockingStream */ 150