New test.
[mono.git] / mcs / class / System / System.Threading / Semaphore.cs
1 //
2 // System.Threading.Semaphore.cs
3 //
4 // Author:
5 //      Sebastien Pouliot  <sebastien@ximian.com>
6 //
7 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29 #if NET_2_0
30
31 using System.Runtime.ConstrainedExecution;
32 using System.Runtime.InteropServices;
33 using System.Security.AccessControl;
34 using System.Runtime.CompilerServices;
35 using System.IO;
36
37 namespace System.Threading {
38
39         [ComVisible (false)]
40         public sealed class Semaphore : WaitHandle {
41
42 #if !TARGET_JVM
43                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
44                 private static extern IntPtr CreateSemaphore_internal (
45                         int initialCount, int maximumCount, string name,
46                         out bool createdNew);
47
48                 [MethodImplAttribute(MethodImplOptions.InternalCall)]
49                 private static extern int ReleaseSemaphore_internal (
50                         IntPtr handle, int releaseCount, out bool fail);
51
52                 [MethodImplAttribute (MethodImplOptions.InternalCall)]
53                 private static extern IntPtr OpenSemaphore_internal (string name, SemaphoreRights rights, out MonoIOError error);
54 #endif
55                 
56                 private Semaphore (IntPtr handle)
57                 {
58                         Handle = handle;
59                 }
60                 
61                 public Semaphore (int initialCount, int maximumCount)
62                         : this (initialCount, maximumCount, null)
63                 {
64                 }
65
66                 public Semaphore (int initialCount, int maximumCount, string name)
67                 {
68                         if (initialCount < 0)
69                                 throw new ArgumentOutOfRangeException ("initialCount", "< 0");
70                         if (maximumCount < 1)
71                                 throw new ArgumentOutOfRangeException ("maximumCount", "< 1");
72                         if (initialCount > maximumCount)
73                                 throw new ArgumentException ("initialCount > maximumCount");
74
75                         bool created;
76                         
77                         Handle = CreateSemaphore_internal (initialCount,
78                                                            maximumCount, name,
79                                                            out created);
80                 }
81
82                 public Semaphore (int initialCount, int maximumCount, string name, out bool createdNew)
83                         : this (initialCount, maximumCount, name, out createdNew, null)
84                 {
85                 }
86
87                 [MonoTODO ("Does not support access control, semaphoreSecurity is ignored")]
88                 public Semaphore (int initialCount, int maximumCount, string name, out bool createdNew, 
89                         SemaphoreSecurity semaphoreSecurity)
90                 {
91                         if (initialCount < 0)
92                                 throw new ArgumentOutOfRangeException ("initialCount", "< 0");
93                         if (maximumCount < 1)
94                                 throw new ArgumentOutOfRangeException ("maximumCount", "< 1");
95                         if (initialCount > maximumCount)
96                                 throw new ArgumentException ("initialCount > maximumCount");
97
98                         Handle = CreateSemaphore_internal (initialCount,
99                                                            maximumCount, name,
100                                                            out createdNew);
101                 }
102
103                 [MonoTODO]
104                 public SemaphoreSecurity GetAccessControl ()
105                 {
106                         throw new NotImplementedException ();
107                 }
108
109                 [PrePrepareMethod]
110                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
111                 public int Release ()
112                 {
113                         return (Release (1));
114                 }
115
116                 [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
117                 public int Release (int releaseCount)
118                 {
119 #if TARGET_JVM
120                         throw new NotImplementedException ();
121 #else
122                         if (releaseCount < 1)
123                                 throw new ArgumentOutOfRangeException ("releaseCount");
124
125                         int ret;
126                         bool fail;
127                         
128                         ret = ReleaseSemaphore_internal (Handle, releaseCount,
129                                                          out fail);
130
131                         if (fail) {
132                                 throw new SemaphoreFullException ();
133                         }
134
135                         return (ret);
136 #endif
137                 }
138
139                 [MonoTODO]
140                 public void SetAccessControl (SemaphoreSecurity semaphoreSecurity)
141                 {
142                         if (semaphoreSecurity == null)
143                                 throw new ArgumentNullException ("semaphoreSecurity");
144
145                         throw new NotImplementedException ();
146                 }
147
148                 // static methods
149
150                 public static Semaphore OpenExisting (string name)
151                 {
152                         return OpenExisting (name, SemaphoreRights.Synchronize | SemaphoreRights.Modify);
153                 }
154
155                 public static Semaphore OpenExisting (string name, SemaphoreRights rights)
156                 {
157                         if (name == null)
158                                 throw new ArgumentNullException ("name");
159                         if ((name.Length ==0) || (name.Length > 260))
160                                 throw new ArgumentException ("name", Locale.GetText ("Invalid length [1-260]."));
161
162 #if !TARGET_JVM
163                         MonoIOError error;
164                         IntPtr handle = OpenSemaphore_internal (name, rights,
165                                                                 out error);
166                         if (handle == (IntPtr)null) {
167                                 if (error == MonoIOError.ERROR_FILE_NOT_FOUND) {
168                                         throw new WaitHandleCannotBeOpenedException (Locale.GetText ("Named Semaphore handle does not exist: ") + name);
169                                 } else if (error == MonoIOError.ERROR_ACCESS_DENIED) {
170                                         throw new UnauthorizedAccessException ();
171                                 } else {
172                                         throw new IOException (Locale.GetText ("Win32 IO error: ") + error.ToString ());
173                                 }
174                         }
175                         
176                         return(new Semaphore (handle));
177 #else
178                         return null;
179 #endif
180                 }
181         }
182 }
183
184 #endif