dotgnu-pnet-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Dotgnu-pnet-commits] CVS: pnetlib/runtime/System/Threading ApartmentSt


From: Rhys Weatherley <address@hidden>
Subject: [Dotgnu-pnet-commits] CVS: pnetlib/runtime/System/Threading ApartmentState.cs,NONE,1.1 CompressedStack.cs,NONE,1.1 IOCompletionCallback.cs,NONE,1.1 LockCookie.cs,NONE,1.1 NativeOverlapped.cs,NONE,1.1 Overlapped.cs,NONE,1.1 ReaderWriterLock.cs,NONE,1.1 RegisteredWaitHandle.cs,1.1,1.2
Date: Tue, 01 Apr 2003 21:23:23 -0500

Update of /cvsroot/dotgnu-pnet/pnetlib/runtime/System/Threading
In directory subversions:/tmp/cvs-serv20430/runtime/System/Threading

Modified Files:
        RegisteredWaitHandle.cs 
Added Files:
        ApartmentState.cs CompressedStack.cs IOCompletionCallback.cs 
        LockCookie.cs NativeOverlapped.cs Overlapped.cs 
        ReaderWriterLock.cs 
Log Message:


Implement missing classes in the "System.Threading" namespace.


--- NEW FILE ---
/*
 * ApartmentState.cs - Implementation of the
 *              "System.Threading.ApartmentState" class.
 *
 * Copyright (C) 2003  Southern Storm Software, Pty Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

namespace System.Threading
{

#if !ECMA_COMPAT

public enum ApartmentState
{
        STA     = 0,
        MTA     = 1,
        Unknown = 2

}; // enum ApartmentState

#endif // !ECMA_COMPAT

}; // namespace System.Threading

--- NEW FILE ---
/*
 * CompressedStack.cs - Implementation of the
 *              "System.Threading.CompressedStack" class.
 *
 * Copyright (C) 2003  Southern Storm Software, Pty Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

namespace System.Threading
{

#if !ECMA_COMPAT

// For compatibility only - don't use this.

public class CompressedStack
{
        // Constructor and destructor.
        private CompressedStack() {}
        ~CompressedStack() {}

        // Get the compressed stack for the current context.
        public static CompressedStack GetCompressedStack()
                        {
                                return new CompressedStack();
                        }

        // Get the unmanaged compressed stack handle.
        public IntPtr UnmanagedCompressedStack { get { return IntPtr.Zero; } }

}; // class CompressedStack

#endif // !ECMA_COMPAT

}; // namespace System.Threading

--- NEW FILE ---
/*
 * IOCompletionCallback.cs - Implementation of the
 *              "System.Threading.IOCompletionCallback" delegate.
 *
 * Copyright (C) 2001  Southern Storm Software, Pty Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

namespace System.Threading
{

#if !ECMA_COMPAT

// For compatibility only - don't use this.

[CLSCompliant(false)]
[Serializable]
public delegate void IOCompletionCallback
        (uint errorCode, uint numBytes, NativeOverlapped *pOVERLAP);

#endif // !ECMA_COMPAT

}; // namespace System.Threading

--- NEW FILE ---
/*
 * LockCookie.cs - Implementation of the
 *              "System.Threading.LockCookie" class.
 *
 * Copyright (C) 2003  Southern Storm Software, Pty Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

namespace System.Threading
{

#if !ECMA_COMPAT

[Serializable]
public struct LockCookie
{
        // Types of lock cookies.
        internal enum CookieType
        {
                None,
                Upgrade,
                Saved

        }; // enum CookieType

        // Internal state.
        internal CookieType type;
        internal Thread thread;
        internal int readCount;
        internal int writeCount;

        // Constructor.
        internal LockCookie(CookieType type, Thread thread,
                                                int readCount, int writeCount)
                        {
                                this.type = type;
                                this.thread = thread;
                                this.readCount = readCount;
                                this.writeCount = writeCount;
                        }

}; // struct LockCookie

#endif // !ECMA_COMPAT

}; // namespace System.Threading

--- NEW FILE ---
/*
 * NativeOverlapped.cs - Implementation of the
 *              "System.Threading.NativeOverlapped" class.
 *
 * Copyright (C) 2003  Southern Storm Software, Pty Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

namespace System.Threading
{

#if !ECMA_COMPAT

using System.Runtime.InteropServices;

// For compatibility only - don't use this.

[StructLayout(LayoutKind.Sequential)]
public struct NativeOverlapped
{
        public int InternalLow;
        public int InternalHigh;
        public int OffsetLow;
        public int OffsetHigh;
        public int EventHandle;

}; // struct NativeOverlapped

#endif // !ECMA_COMPAT

}; // namespace System.Threading

--- NEW FILE ---
/*
 * Overlapped.cs - Implementation of the
 *              "System.Threading.Overlapped" class.
 *
 * Copyright (C) 2003  Southern Storm Software, Pty Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

namespace System.Threading
{

#if !ECMA_COMPAT

// For compatibility only - don't use this.

public class Overlapped
{
        // Internal state.
        private int offsetLo;
        private int offsetHi;
        private int hEvent;
        private IAsyncResult ar;

        // Constructors.
        public Overlapped() {}
        public Overlapped(int offsetLo, int offsetHi, int hEvent, IAsyncResult 
ar)
                        {
                                this.offsetLo = offsetLo;
                                this.offsetHi = offsetHi;
                                this.hEvent = hEvent;
                                this.ar = ar;
                        }

        // Get or set this object's properties.
        public int OffsetLow
                        {
                                get
                                {
                                        return offsetLo;
                                }
                                set
                                {
                                        offsetLo = value;
                                }
                        }
        public int OffsetHigh
                        {
                                get
                                {
                                        return offsetHi;
                                }
                                set
                                {
                                        offsetHi = value;
                                }
                        }
        public int EventHandle
                        {
                                get
                                {
                                        return hEvent;
                                }
                                set
                                {
                                        hEvent = value;
                                }
                        }
        public IAsyncResult AsyncResult
                        {
                                get
                                {
                                        return ar;
                                }
                                set
                                {
                                        ar = value;
                                }
                        }

        // Unpack a native overlapped structure.
        [CLSCompliant(false)]
        public static unsafe Overlapped Unpack
                                (NativeOverlapped *nativeOverlappedPtr)
                        {
                                if(((IntPtr)nativeOverlappedPtr) == IntPtr.Zero)
                                {
                                        throw new 
ArgumentNullException("nativeOverlappedPtr");
                                }
                                return new 
Overlapped(nativeOverlappedPtr->OffsetLow,
                                                                          
nativeOverlappedPtr->OffsetHigh,
                                                                          
nativeOverlappedPtr->EventHandle,
                                                                          null);
                        }

        // Free a native overlapped structure.
        [CLSCompliant(false)]
        public static unsafe void Free(NativeOverlapped *nativeOverlappedPtr)
                        {
                                // Since there is no way to allocate a native 
overlapped
                                // structure in this implementation, the only 
thing we
                                // need to do here is check for null.
                                if(((IntPtr)nativeOverlappedPtr) == IntPtr.Zero)
                                {
                                        throw new 
ArgumentNullException("nativeOverlappedPtr");
                                }
                        }

}; // class Overlapped

#endif // !ECMA_COMPAT

}; // namespace System.Threading

--- NEW FILE ---
/*
 * ReaderWriterLock.cs - Implementation of the
 *              "System.Threading.ReaderWriterLock" class.
 *
 * Copyright (C) 2003  Southern Storm Software, Pty Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

namespace System.Threading
{

#if !ECMA_COMPAT

public sealed class ReaderWriterLock
{
        // Lock information for a thread.
        private sealed class LockInfo
        {
                public LockInfo next;
                public Thread thread;
                public int numReadLocks;
                public int numWriteLocks;

                public LockInfo(Thread thread, LockInfo next)
                                {
                                        this.next = next;
                                        this.thread = thread;
                                        this.numReadLocks = 0;
                                        this.numWriteLocks = 0;
                                }

        }; // class LockInfo

        // Internal state.
        private int numReadLocks;
        private int numWriteLocks;
        private int seqNum;
        private int lastWriteSeqNum;
        private LockInfo lockList;

        // Constructor.
        public ReaderWriterLock()
                        {
                                numReadLocks = 0;
                                numWriteLocks = 0;
                                seqNum = 0;
                                lastWriteSeqNum = -1;
                                lockList = null;
                        }

        // Get the lock information for the current thread.
        private LockInfo GetLockInfo()
                        {
                                Thread thread = Thread.CurrentThread;
                                LockInfo info = lockList;
                                while(info != null)
                                {
                                        if(info.thread == thread)
                                        {
                                                return info;
                                        }
                                        info = info.next;
                                }
                                return null;
                        }

        // Get the lock information for the current thread, creating
        // a new information object if one doesn't exist yet.
        private LockInfo GetOrCreateLockInfo()
                        {
                                Thread thread = Thread.CurrentThread;
                                LockInfo info = lockList;
                                while(info != null)
                                {
                                        if(info.thread == thread)
                                        {
                                                return info;
                                        }
                                        info = info.next;
                                }
                                info = new LockInfo(thread, lockList);
                                lockList = info;
                                return info;
                        }

        // Acquire the read lock.
        public void AcquireReaderLock(int millisecondsTimeout)
                        {
                                if(millisecondsTimeout < -1)
                                {
                                        throw new ArgumentOutOfRangeException
                                                ("millisecondsTimeout",
                                                 _("ArgRange_NonNegOrNegOne"));
                                }
                                lock(this)
                                {
                                        // Get the lock information for this 
thread.
                                        LockInfo info = GetOrCreateLockInfo();

                                        // Block if some other thread has the 
writer lock.
                                        if(millisecondsTimeout == -1)
                                        {
                                                while(info.numWriteLocks == 0 
&& numWriteLocks > 0)
                                                {
                                                        if(!Monitor.Wait(this))
                                                        {
                                                                return;
                                                        }
                                                }
                                        }
                                        else
                                        {
                                                DateTime expire = 
DateTime.UtcNow +
                                                        new 
TimeSpan(millisecondsTimeout *
                                                                                
 TimeSpan.TicksPerMillisecond);
                                                DateTime now;
                                                int ms;
                                                while(info.numWriteLocks == 0 
&& numWriteLocks > 0)
                                                {
                                                        now = DateTime.UtcNow;
                                                        if(now >= expire)
                                                        {
                                                                return;
                                                        }
                                                        ms = (int)((expire - 
now).Ticks /
                                                                                
TimeSpan.TicksPerMillisecond);
                                                        if(!Monitor.Wait(this, 
ms))
                                                        {
                                                                return;
                                                        }
                                                }
                                        }

                                        // Update the thread and global read 
lock counts.
                                        ++(info.numReadLocks);
                                        ++numReadLocks;
                                }
                        }
        public void AcquireReaderLock(TimeSpan timeout)
                        {
                                
AcquireReaderLock(Monitor.TimeSpanToMS(timeout));
                        }

        // Acquire the write lock.
        public void AcquireWriterLock(int millisecondsTimeout)
                        {
                                if(millisecondsTimeout < -1)
                                {
                                        throw new ArgumentOutOfRangeException
                                                ("millisecondsTimeout",
                                                 _("ArgRange_NonNegOrNegOne"));
                                }
                                lock(this)
                                {
                                        // Get the lock information for this 
thread.
                                        LockInfo info = GetOrCreateLockInfo();

                                        // Bail out early if we already have 
the writer lock.
                                        if(info.numWriteLocks > 0)
                                        {
                                                ++(info.numWriteLocks);
                                                ++numWriteLocks;
                                                lastWriteSeqNum = ++seqNum;
                                                return;
                                        }

                                        // Block while some other thread has 
the read or write lock.
                                        if(millisecondsTimeout == -1)
                                        {
                                                while(numReadLocks > 0 || 
numWriteLocks > 0)
                                                {
                                                        if(!Monitor.Wait(this))
                                                        {
                                                                return;
                                                        }
                                                }
                                        }
                                        else
                                        {
                                                DateTime expire = 
DateTime.UtcNow +
                                                        new 
TimeSpan(millisecondsTimeout *
                                                                                
 TimeSpan.TicksPerMillisecond);
                                                DateTime now;
                                                int ms;
                                                while(numReadLocks > 0 || 
numWriteLocks > 0)
                                                {
                                                        now = DateTime.UtcNow;
                                                        if(now >= expire)
                                                        {
                                                                return;
                                                        }
                                                        ms = (int)((expire - 
now).Ticks /
                                                                                
TimeSpan.TicksPerMillisecond);
                                                        if(!Monitor.Wait(this, 
ms))
                                                        {
                                                                return;
                                                        }
                                                }
                                        }

                                        // Update the thread and global write 
lock counts.
                                        ++(info.numWriteLocks);
                                        ++numWriteLocks;
                                        lastWriteSeqNum = ++seqNum;
                                }
                        }
        public void AcquireWriterLock(TimeSpan timeout)
                        {
                                
AcquireWriterLock(Monitor.TimeSpanToMS(timeout));
                        }

        // Determine if there have been any writers since a particular seqnum.
        public bool AnyWritersSince(int seqNum)
                        {
                                lock(this)
                                {
                                        if(seqNum >= 0 && seqNum < 
lastWriteSeqNum)
                                        {
                                                return true;
                                        }
                                        else
                                        {
                                                return false;
                                        }
                                }
                        }

        // Downgrade the current thread from a writer lock.
        public void DowngradeFromWriterLock(ref LockCookie lockCookie)
                        {
                                lock(this)
                                {
                                        // Get the lock information for this 
thread.
                                        LockInfo info = GetLockInfo();
                                        if(info == null)
                                        {
                                                return;
                                        }

                                        // Bail out if the cookie is not 
"Upgrade".
                                        if(lockCookie.type != 
LockCookie.CookieType.Upgrade ||
                                           lockCookie.thread != 
Thread.CurrentThread)
                                        {
                                                return;
                                        }

                                        // Restore the thread to its previous 
lock state.
                                        RestoreLockState(info, 
lockCookie.readCount,
                                                                         
lockCookie.writeCount);
                                }
                        }

        // Release all locks for the current thread and save them.
        public LockCookie ReleaseLock()
                        {
                                lock(this)
                                {
                                        // Get the lock information for this 
thread.
                                        LockInfo info = GetLockInfo();
                                        if(info == null)
                                        {
                                                return new LockCookie
                                                        
(LockCookie.CookieType.None,
                                                         Thread.CurrentThread, 
0, 0);
                                        }

                                        // Bail out if the thread doesn't have 
any locks.
                                        if(info.numReadLocks == 0 && 
info.numWriteLocks == 0)
                                        {
                                                return new LockCookie
                                                        
(LockCookie.CookieType.None,
                                                         Thread.CurrentThread, 
0, 0);
                                        }

                                        // Copy the lock infomation into the 
cookie.
                                        LockCookie cookie = new LockCookie
                                                (LockCookie.CookieType.Saved,
                                                 Thread.CurrentThread,
                                                 info.numReadLocks, 
info.numWriteLocks);

                                        // Release the active locks.
                                        numReadLocks -= info.numReadLocks;
                                        numWriteLocks -= info.numWriteLocks;
                                        info.numReadLocks = 0;
                                        info.numWriteLocks = 0;

                                        // Determine if we need to wake up a 
waiting thread.
                                        if(numReadLocks == 0 || numWriteLocks 
== 0)
                                        {
                                                Monitor.Pulse(this);
                                        }

                                        // Return the cookie to the caller.
                                        return cookie;
                                }
                        }

        // Release the read lock.
        public void ReleaseReaderLock()
                        {
                                lock(this)
                                {
                                        // Get the lock information for this 
thread.
                                        LockInfo info = GetLockInfo();
                                        if(info == null)
                                        {
                                                return;
                                        }

                                        // Save the global write lock count.
                                        int saveRead = numReadLocks;
                                        int saveWrite = numWriteLocks;

                                        // Update the thread and global lock 
count values.
                                        if(info.numReadLocks > 0)
                                        {
                                                --(info.numReadLocks);
                                                --numReadLocks;
                                        }

                                        // Determine if we need to wake up a 
waiting thread.
                                        if(saveRead > numReadLocks && 
numReadLocks == 0)
                                        {
                                                Monitor.Pulse(this);
                                        }
                                        else if(saveWrite > numWriteLocks && 
numWriteLocks == 0)
                                        {
                                                Monitor.Pulse(this);
                                        }
                                }
                        }

        // Release the write lock.
        public void ReleaseWriterLock()
                        {
                                lock(this)
                                {
                                        // Get the lock information for this 
thread.
                                        LockInfo info = GetLockInfo();
                                        if(info == null)
                                        {
                                                return;
                                        }

                                        // Bail out with an exception if we 
have read locks.
                                        if(info.numReadLocks > 0)
                                        {
                                                throw new 
ApplicationException(_("Invalid_RWLock"));
                                        }

                                        // Update the thread and global lock 
count values.
                                        if(info.numWriteLocks == 0)
                                        {
                                                return;
                                        }
                                        --(info.numWriteLocks);
                                        --numWriteLocks;

                                        // Determine if we need to wake up a 
waiting thread.
                                        if(numWriteLocks == 0)
                                        {
                                                Monitor.Pulse(this);
                                        }
                                }
                        }

        // Restore the lock state for the current thread.
        private void RestoreLockState(LockInfo info, int readCount, int 
writeCount)
                        {
                                // Save the current global lock state.
                                int saveRead = numReadLocks;
                                int saveWrite = numWriteLocks;

                                // Remove the locks that are currently held by 
the thread.
                                numReadLocks -= info.numReadLocks;
                                numWriteLocks -= info.numWriteLocks;
                                info.numReadLocks = 0;
                                info.numWriteLocks = 0;

                                // Wake up any waiting threads.
                                if(saveRead > numReadLocks && numReadLocks == 0)
                                {
                                        Monitor.Pulse(this);
                                }
                                else if(saveWrite > numWriteLocks && 
numWriteLocks == 0)
                                {
                                        Monitor.Pulse(this);
                                }

                                // Re-acquire the locks based upon the type 
required.
                                if(readCount > 0 && writeCount == 0)
                                {
                                        // Re-acquire read locks only.
                                        while(numWriteLocks > 0)
                                        {
                                                Monitor.Wait(this);
                                        }
                                        info.numReadLocks += readCount;
                                        numReadLocks += readCount;
                                }
                                else if(readCount == 0 && writeCount > 0)
                                {
                                        // Re-acquire write locks only.
                                        while(numReadLocks > 0 && numWriteLocks 
> 0)
                                        {
                                                Monitor.Wait(this);
                                        }
                                        info.numWriteLocks += writeCount;
                                        numWriteLocks += writeCount;
                                }
                                else if(readCount > 0 && writeCount > 0)
                                {
                                        // Re-acquire both read and write locks.
                                        while(numWriteLocks > 0)
                                        {
                                                Monitor.Wait(this);
                                        }
                                        info.numReadLocks += readCount;
                                        numReadLocks += readCount;
                                        info.numWriteLocks += writeCount;
                                        numWriteLocks += writeCount;
                                }
                        }

        // Restore all locks for the curent thread to a previous "Release" 
value.
        public void RestoreLock(ref LockCookie lockCookie)
                        {
                                lock(this)
                                {
                                        // Get the lock information for this 
thread.
                                        LockInfo info = GetLockInfo();
                                        if(info == null)
                                        {
                                                return;
                                        }

                                        // Bail out if the cookie is not 
"Saved" or if
                                        // we have prevailing locks at the 
moment.
                                        if(lockCookie.type != 
LockCookie.CookieType.Saved ||
                                           lockCookie.thread != 
Thread.CurrentThread ||
                                           info.numReadLocks > 0 ||
                                           info.numWriteLocks > 0)
                                        {
                                                return;
                                        }

                                        // Restore the thread to its previous 
lock state.
                                        RestoreLockState(info, 
lockCookie.readCount,
                                                                         
lockCookie.writeCount);
                                }
                        }

        // Update the current thread to a writer lock.
        public LockCookie UpgradeToWriterLock(int millisecondsTimeout)
                        {
                                LockCookie cookie;
                                if(millisecondsTimeout < -1)
                                {
                                        throw new ArgumentOutOfRangeException
                                                ("millisecondsTimeout",
                                                 _("ArgRange_NonNegOrNegOne"));
                                }
                                lock(this)
                                {
                                        // Get the lock information for this 
thread.
                                        LockInfo info = GetOrCreateLockInfo();

                                        // Bail out early if we already have 
the writer lock.
                                        if(info.numWriteLocks > 0)
                                        {
                                                cookie = new LockCookie
                                                        
(LockCookie.CookieType.Upgrade,
                                                         Thread.CurrentThread,
                                                         info.numReadLocks, 
info.numWriteLocks);
                                                ++(info.numWriteLocks);
                                                ++numWriteLocks;
                                                lastWriteSeqNum = ++seqNum;
                                                return cookie;
                                        }

                                        // If we have the read lock, then 
upgrade it.
                                        if(info.numReadLocks > 0)
                                        {
                                                cookie = new LockCookie
                                                        
(LockCookie.CookieType.Upgrade,
                                                         Thread.CurrentThread,
                                                         info.numReadLocks, 
info.numWriteLocks);
                                                info.numWriteLocks += 
info.numReadLocks;
                                                numReadLocks -= 
info.numReadLocks;
                                                numWriteLocks -= 
info.numReadLocks;
                                                info.numReadLocks = 0;
                                                lastWriteSeqNum = ++seqNum;
                                                return cookie;
                                        }

                                        // Block while some other thread has 
the read or write lock.
                                        if(millisecondsTimeout == -1)
                                        {
                                                while(numReadLocks > 0 || 
numWriteLocks > 0)
                                                {
                                                        if(!Monitor.Wait(this))
                                                        {
                                                                return new 
LockCookie
                                                                        
(LockCookie.CookieType.None,
                                                                         
Thread.CurrentThread, 0, 0);
                                                        }
                                                }
                                        }
                                        else
                                        {
                                                DateTime expire = 
DateTime.UtcNow +
                                                        new 
TimeSpan(millisecondsTimeout *
                                                                                
 TimeSpan.TicksPerMillisecond);
                                                DateTime now;
                                                int ms;
                                                while(numReadLocks > 0 || 
numWriteLocks > 0)
                                                {
                                                        now = DateTime.UtcNow;
                                                        if(now >= expire)
                                                        {
                                                                return new 
LockCookie
                                                                        
(LockCookie.CookieType.None,
                                                                         
Thread.CurrentThread, 0, 0);
                                                        }
                                                        ms = (int)((expire - 
now).Ticks /
                                                                                
TimeSpan.TicksPerMillisecond);
                                                        if(!Monitor.Wait(this, 
ms))
                                                        {
                                                                return new 
LockCookie
                                                                        
(LockCookie.CookieType.None,
                                                                         
Thread.CurrentThread, 0, 0);
                                                        }
                                                }
                                        }

                                        // Update the thread and global write 
lock counts.
                                        cookie = new LockCookie
                                                (LockCookie.CookieType.Upgrade,
                                                 Thread.CurrentThread,
                                                 info.numReadLocks, 
info.numWriteLocks);
                                        ++(info.numWriteLocks);
                                        ++numWriteLocks;
                                        lastWriteSeqNum = ++seqNum;
                                        return cookie;
                                }
                        }
        public LockCookie UpgradeToWriterLock(TimeSpan timeout)
                        {
                                return 
UpgradeToWriterLock(Monitor.TimeSpanToMS(timeout));
                        }

        // Determine if the read lock is held by the current thread.
        public bool IsReaderLockHeld
                        {
                                get
                                {
                                        lock(this)
                                        {
                                                LockInfo info = GetLockInfo();
                                                if(info != null)
                                                {
                                                        return 
(info.numReadLocks > 0);
                                                }
                                                else
                                                {
                                                        return false;
                                                }
                                        }
                                }
                        }

        // Determine if the write lock is held by the current thread.
        public bool IsWriterLockHeld
                        {
                                get
                                {
                                        lock(this)
                                        {
                                                LockInfo info = GetLockInfo();
                                                if(info != null)
                                                {
                                                        return 
(info.numWriteLocks > 0);
                                                }
                                                else
                                                {
                                                        return false;
                                                }
                                        }
                                }
                        }

        // Get the writer sequence number.
        public int WriterSeqNum
                        {
                                get
                                {
                                        lock(this)
                                        {
                                                return seqNum;
                                        }
                                }
                        }

}; // class ReaderWriterLock

#endif // !ECMA_COMPAT

}; // namespace System.Threading

Index: RegisteredWaitHandle.cs
===================================================================
RCS file: 
/cvsroot/dotgnu-pnet/pnetlib/runtime/System/Threading/RegisteredWaitHandle.cs,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -r1.1 -r1.2
*** RegisteredWaitHandle.cs     16 Feb 2003 10:46:50 -0000      1.1
--- RegisteredWaitHandle.cs     2 Apr 2003 02:23:21 -0000       1.2
***************
*** 1,9 ****
  /*
!  * RegisteredWaitHandle.cs - Implementation of 
!  *                                            "RegisteredWaitHandle" class.
   *
   * Copyright (C) 2003  Southern Storm Software, Pty Ltd.
-  * 
-  * Contributed by Gopal.V 
   *
   * This program is free software; you can redistribute it and/or modify
--- 1,7 ----
  /*
!  * RegisteredWaitHandle.cs - Implementation of the
!  *            "System.Threading.RegisteredWaitHandle" class.
   *
   * Copyright (C) 2003  Southern Storm Software, Pty Ltd.
   *
   * This program is free software; you can redistribute it and/or modify
***************
*** 22,41 ****
   */
  
! using System;
  
  #if !ECMA_COMPAT
  
! namespace System.Threading
  {
-       public sealed class RegisteredWaitHandle: MarshalByRefObject
-       {
-               [TODO]
-               public bool Unregister(WaitHandle waitObject)
-               {
-                        throw new NotImplementedException("Unregister");
-               }
  
!       }
! }//namespace
  
! #endif
--- 20,43 ----
   */
  
! namespace System.Threading
! {
  
  #if !ECMA_COMPAT
  
! public sealed class RegisteredWaitHandle : MarshalByRefObject
  {
  
!       // Constructor.
!       internal RegisteredWaitHandle() {}
! 
!       // Unregister using a specific wait object.
!       public bool Unregister(WaitHandle waitObject)
!                       {
!                               return true;
!                       }
! 
! }; // class RegisteredWaitHandle
! 
! #endif // !ECMA_COMPAT
  
! }; // namespace System.Threading





reply via email to

[Prev in Thread] Current Thread [Next in Thread]