]> err.no Git - sope/blob - sope-core/NGStreams/NGLockingStream.m
Drop apache 1 build-dependency
[sope] / sope-core / NGStreams / NGLockingStream.m
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;
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 */