[Timer] Use a WaitHandle instead of Wait/Pulse
[mono.git] / mcs / class / corlib / System.Threading / EventWaitHandle.cs
index 3cb56ae2435eac0f83b36ae31d11f6f55ad68a82..de747e506bb1f1282845340d3e2a655ff9e21061 100644 (file)
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if NET_2_0
-
+using System.IO;
+using System.Runtime.InteropServices;
+#if !NET_2_1
 using System.Security.AccessControl;
+#endif
 
 namespace System.Threading
 {
+       [ComVisible (true)]
        public class EventWaitHandle : WaitHandle
        {
+               private EventWaitHandle (IntPtr handle)
+               {
+                       Handle = handle;
+               }
+
+               private bool IsManualReset (EventResetMode mode)
+               {
+                       if ((mode < EventResetMode.AutoReset) || (mode > EventResetMode.ManualReset))
+                               throw new ArgumentException ("mode");
+                       return (mode == EventResetMode.ManualReset);
+               }
+               
                public EventWaitHandle (bool initialState, EventResetMode mode)
                {
-                       Handle = NativeEventCalls.CreateEvent_internal ((mode == EventResetMode.ManualReset), initialState, null);
+                       bool created;
+                       bool manual = IsManualReset (mode);
+                       Handle = NativeEventCalls.CreateEvent_internal (manual, initialState, null, out created);
                }
                
                public EventWaitHandle (bool initialState, EventResetMode mode,
                                        string name)
                {
-                       Handle = NativeEventCalls.CreateEvent_internal ((mode == EventResetMode.ManualReset), initialState, name);
+                       bool created;
+                       bool manual = IsManualReset (mode);
+                       Handle = NativeEventCalls.CreateEvent_internal (manual, initialState, name, out created);
                }
                
-               [MonoTODO ("Implement createdNew")]
                public EventWaitHandle (bool initialState, EventResetMode mode,
                                        string name, out bool createdNew)
                {
-                       Handle = NativeEventCalls.CreateEvent_internal ((mode == EventResetMode.ManualReset), initialState, name);
-                       createdNew = false;
+                       bool manual = IsManualReset (mode);
+                       Handle = NativeEventCalls.CreateEvent_internal (manual, initialState, name, out createdNew);
                }
-               
-               [MonoTODO ("Implement createdNew and access control")]
+#if !NET_2_1
+               [MonoTODO ("Implement access control")]
                public EventWaitHandle (bool initialState, EventResetMode mode,
                                        string name, out bool createdNew,
                                        EventWaitHandleSecurity eventSecurity)
                {
-                       Handle = NativeEventCalls.CreateEvent_internal ((mode == EventResetMode.ManualReset), initialState, name);
-                       createdNew = false;
+                       bool manual = IsManualReset (mode);
+                       Handle = NativeEventCalls.CreateEvent_internal (manual, initialState, name, out createdNew);
                }
                
                [MonoTODO]
@@ -68,18 +86,37 @@ namespace System.Threading
                {
                        throw new NotImplementedException ();
                }
-               
+
                public static EventWaitHandle OpenExisting (string name)
                {
                        return(OpenExisting (name, EventWaitHandleRights.Synchronize | EventWaitHandleRights.Modify));
                }
 
-               [MonoTODO]
                public static EventWaitHandle OpenExisting (string name, EventWaitHandleRights rights)
                {
-                       throw new NotImplementedException ();
+                       if (name == null) {
+                               throw new ArgumentNullException ("name");
+                       }
+                       if ((name.Length == 0) ||
+                           (name.Length > 260)) {
+                               throw new ArgumentException ("name", Locale.GetText ("Invalid length [1-260]."));
+                       }
+                       
+                       MonoIOError error;
+                       IntPtr handle = NativeEventCalls.OpenEvent_internal (name, rights, out error);
+                       if (handle == (IntPtr)null) {
+                               if (error == MonoIOError.ERROR_FILE_NOT_FOUND) {
+                                       throw new WaitHandleCannotBeOpenedException (Locale.GetText ("Named Event handle does not exist: ") + name);
+                               } else if (error == MonoIOError.ERROR_ACCESS_DENIED) {
+                                       throw new UnauthorizedAccessException ();
+                               } else {
+                                       throw new IOException (Locale.GetText ("Win32 IO error: ") + error.ToString ());
+                               }
+                       }
+                       
+                       return(new EventWaitHandle (handle));
                }
-               
+#endif
                public bool Reset ()
                {
                        CheckDisposed ();
@@ -93,13 +130,12 @@ namespace System.Threading
                        
                        return (NativeEventCalls.SetEvent_internal (Handle));
                }
-
+#if !NET_2_1
                [MonoTODO]
                public void SetAccessControl (EventWaitHandleSecurity eventSecurity)
                {
                        throw new NotImplementedException ();
                }
+#endif
        }
 }
-
-#endif