Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Moved SafeWaitHandle and cancellationToken to shared #18662

Merged
merged 9 commits into from
Jun 27, 2018
Merged

Moved SafeWaitHandle and cancellationToken to shared #18662

merged 9 commits into from
Jun 27, 2018

Conversation

Anipik
Copy link

@Anipik Anipik commented Jun 26, 2018

Corert PR :- dotnet/corert#6020

return Win32Native.CloseHandle(handle);
#if CORECLR && PLATFORM_UNIX
WaitSubsystem.DeleteHandle(handle);
return true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: indenting is off

{
return Win32Native.CloseHandle(handle);
#if CORECLR && PLATFORM_UNIX
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we please avoid adding PLATFORM_UNIX and use !PLATFORM_WINDOWS instead? I'd like to keep things consistent across the codebase, and to me it's confusing when multiple constants are used for the same purpose.

{
return Win32Native.CloseHandle(handle);
#if CORECLR && PLATFORM_UNIX
WaitSubsystem.DeleteHandle(handle);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is coreclr being changed to use WaitSubsystem.DeleteHandle here?

/// <exception cref="T:System.ObjectDisposedException">The associated <see
/// cref="T:System.Threading.CancellationTokenSource">CancellationTokenSource</see> has been disposed.</exception>
#if CORECLR
public
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this being made public on coreclr?


private bool _disposed;

// we track the running callback to assist ctr.Dispose() to wait for the target callback to complete.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CancellationTokenSource in coreclr is newer than the one in corert, and these fields were all reordered in coreclr... I'd prefer if we use the coreclr ordering / commenting / etc.


// Lazily-initialize the handle.
var mre = new ManualResetEvent(false);
ManualResetEvent mre = new ManualResetEvent(false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: var was fine

/// such that one callback throwing an exception will not prevent other registered callbacks from being executed.
/// </para>
/// <para>
/// The <see cref="ExecutionContext"/> that was captured when each callback was registered
/// will be reestablished when the callback is invoked.
/// </para>
/// </para>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The indenting here was better before.

private void ExecuteCallbackHandlers(bool throwOnFirstException)
{
Debug.Assert(IsCancellationRequested, "ExecuteCallbackHandlers should only be called after setting IsCancellationRequested->true");

Debug.Assert(ThreadIDExecutingCallbacks != -1, "ThreadIDExecutingCallbacks should have been set.");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure this assert is valid? It looks wrong to me.

@@ -97,8 +86,6 @@ void IThreadPoolWorkItem.ExecuteWorkItem()
bool setSuccessfully = TrySetResult(true);
Debug.Assert(setSuccessfully, "Should have been able to complete task");
}

void IThreadPoolWorkItem.MarkAborted(ThreadAbortException tae) { /* nop */ }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still part of the interface and can't be removed. Does this compile?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it compiles perfectly fine. should I add it again ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should I add it again ?

Yes, it should be added back. I expect it's picking up the base type's implementation of the interface, and that's why it's still compiling successfully without this, but in doing so removing this line is potentially changing the behavior here (even though thread aborts are deprecated and in practice we shouldn't be hitting them outside of a debugging environment).

@@ -35,9 +24,14 @@ public SafeWaitHandle(IntPtr existingHandle, bool ownsHandle) : base(ownsHandle)
SetHandle(existingHandle);
}

override protected bool ReleaseHandle()
protected override bool ReleaseHandle()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be nice to split into .Windows.cs and .Unix.cs files.

@@ -517,7 +503,7 @@ private bool WaitUntilCountOrTimeout(int millisecondsTimeout, uint startTime, Ca
/// <returns>A task that will complete when the semaphore has been entered.</returns>
public Task WaitAsync()
{
return WaitAsync(Timeout.Infinite, default);
return WaitAsync(Timeout.Infinite, default(CancellationToken));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was removed in #17451 . Why add it back?

@@ -55,7 +43,7 @@ public class SemaphoreSlim : IDisposable
// The number of synchronously waiting threads, it is set to zero in the constructor and increments before blocking the
// threading and decrements it back after that. It is used as flag for the release call to know if there are
// waiting threads in the monitor or not.
private int m_waitCount;
private volatile int m_waitCount;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this need to be volatile?

Copy link
Author

@Anipik Anipik Jun 27, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will be accessed by the multiple threads as it keeps the record of the waiting threads present in the monitor

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is always accessed under a lock as far as I can tell. Did you happen to trace down when was this volatile added or removed?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah you are right. I missed the lock part. It was removed here #13766 due to the reason you mentioned

// spin, contention, etc. The usual number of spin iterations that would otherwise be used here is increased to
// lessen that extra expense of doing a proper wait.
var spinner = new SpinWait();
#if CORECLR
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this ifdef really required? Looks like a performance fix that did not get ported to CoreRT.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah you are right. 0799da2

is checking the m_currentCount == 0 in if condition rather than in while condition has some effect on performance ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

m_currentCount == 0 in if condition rather than in while condition has some effect on performance

That alone - no. However, there are other differences.

Just keep the CoreCLR impl here. It is the right one.

@Anipik
Copy link
Author

Anipik commented Jun 27, 2018

@jkotas is it ready to merge ?

@jkotas
Copy link
Member

jkotas commented Jun 27, 2018

It looks fine to me, but it would be nice to wait till morning in case Stephen has more comments.

@@ -578,7 +565,7 @@ public Task<bool> WaitAsync(int millisecondsTimeout)
/// </exception>
/// <exception cref="T:System.ArgumentOutOfRangeException">
/// <paramref name="timeout"/> is a negative number other than -1 milliseconds, which represents
/// an infinite time-out -or- timeout is greater than <see cref="System.int.MaxValue"/>.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: The original version of this comment looked right. The new version does not make sense to me.

@Anipik
Copy link
Author

Anipik commented Jun 27, 2018

@stephentoub can I go ahead and merge it ?

@jkotas jkotas merged commit 11c9d85 into dotnet:master Jun 27, 2018
dotnet-maestro-bot pushed a commit to dotnet-maestro-bot/corefx that referenced this pull request Jun 27, 2018
…18662)

* Moving SafeWaitHandle to shared

* Moved CancellationToken to shared

* _ remove from variable names

* Default change to Default(Token) and minor changes

* Fixing coreclr unix build

* moving semaphoreSlim to shared

* splitting safeWaitHandle to .windows and .unix

Signed-off-by: dotnet-bot <[email protected]>
dotnet-maestro-bot pushed a commit to dotnet-maestro-bot/corert that referenced this pull request Jun 27, 2018
…18662)

* Moving SafeWaitHandle to shared

* Moved CancellationToken to shared

* _ remove from variable names

* Default change to Default(Token) and minor changes

* Fixing coreclr unix build

* moving semaphoreSlim to shared

* splitting safeWaitHandle to .windows and .unix

Signed-off-by: dotnet-bot <[email protected]>
Anipik added a commit to dotnet/corefx that referenced this pull request Jun 27, 2018
…18662)

* Moving SafeWaitHandle to shared

* Moved CancellationToken to shared

* _ remove from variable names

* Default change to Default(Token) and minor changes

* Fixing coreclr unix build

* moving semaphoreSlim to shared

* splitting safeWaitHandle to .windows and .unix

Signed-off-by: dotnet-bot <[email protected]>
jkotas pushed a commit to dotnet/corert that referenced this pull request Jun 27, 2018
…18662)

* Moving SafeWaitHandle to shared

* Moved CancellationToken to shared

* _ remove from variable names

* Default change to Default(Token) and minor changes

* Fixing coreclr unix build

* moving semaphoreSlim to shared

* splitting safeWaitHandle to .windows and .unix

Signed-off-by: dotnet-bot <[email protected]>
@stephentoub
Copy link
Member

Sorry, just saw the question to me... LGTM.

@Anipik
Copy link
Author

Anipik commented Jun 28, 2018

np :)

@Anipik Anipik deleted the safeWaitHandle branch April 8, 2019 18:49
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
…18662)

* Moving SafeWaitHandle to shared

* Moved CancellationToken to shared

* _ remove from variable names

* Default change to Default(Token) and minor changes

* Fixing coreclr unix build

* moving semaphoreSlim to shared

* splitting safeWaitHandle to .windows and .unix


Commit migrated from dotnet/coreclr@11c9d85
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants