Skip to content

Commit

Permalink
[CoreFoundation] Refactor Dispatch code to take advantage of recent c…
Browse files Browse the repository at this point in the history
…ode improvements. (#4939)

* [CoreFoundation] Make DispatchObject inherit from NativeObject to share more code.

* [CoreFoundation] Replace calls to Check () with calls to GetCheckedHandle () to reuse more code.

* [CoreFoundation] Simplify a bit by reusing code in base constructors.

* [CoreFoundation] Use Handle instead of handle.

* [CoreFoundation] Use InitializeHandle instead of setting the 'handle' field.

* [CoreFoundation] Remove temporary 'handle' field.

* [CoreFoundation] Remove needless 'unsafe' blocks.

* Reintroduce DispatchObject.Check, since it's public API.
  • Loading branch information
rolfbjarne authored Oct 11, 2018
1 parent 73fbb53 commit f96faaa
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 170 deletions.
108 changes: 39 additions & 69 deletions src/CoreFoundation/Dispatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Threading;
using ObjCRuntime;
Expand All @@ -47,26 +48,18 @@ public enum DispatchQueuePriority : int {
Background = Int16.MinValue
}

public abstract class DispatchObject : INativeObject
#if !COREBUILD
, IDisposable
#endif
public abstract class DispatchObject : NativeObject
{
#if !COREBUILD
internal IntPtr handle;

//
// Constructors and lifecycle
//
[Preserve (Conditional = true)]
internal DispatchObject (IntPtr handle, bool owns)
: base (handle, owns)
{
if (handle == IntPtr.Zero)
throw new ArgumentNullException ("handle");

this.handle = handle;
if (!owns)
dispatch_retain (handle);
}

internal DispatchObject ()
Expand All @@ -79,27 +72,14 @@ internal DispatchObject ()
[DllImport (Constants.libcLibrary)]
extern static IntPtr dispatch_retain (IntPtr o);

~DispatchObject ()
{
Dispose (false);
}

public void Dispose ()
protected override void Retain ()
{
Dispose (true);
GC.SuppressFinalize (this);
dispatch_retain (Handle);
}

public IntPtr Handle {
get { return handle; }
}

protected virtual void Dispose (bool disposing)
protected override void Release ()
{
if (handle != IntPtr.Zero){
dispatch_release (handle);
handle = IntPtr.Zero;
}
dispatch_release (Handle);
}

public static bool operator == (DispatchObject a, DispatchObject b)
Expand All @@ -114,7 +94,7 @@ protected virtual void Dispose (bool disposing)
} else {
if (ob == null)
return false;
return a.handle == b.handle;
return a.Handle == b.Handle;
}
}

Expand All @@ -128,19 +108,22 @@ public override bool Equals (object other)
var od = other as DispatchQueue;
if (od == null)
return false;
return od.handle == handle;
return od.Handle == Handle;
}

public override int GetHashCode ()
{
return (int) handle;
return (int) Handle;
}

#if !XAMCORE_4_0
[EditorBrowsable (EditorBrowsableState.Never)]
[Obsolete ("Use 'GetCheckedHandle' instead.")]
protected void Check ()
{
if (handle == IntPtr.Zero)
throw new ObjectDisposedException (GetType ().ToString ());
}
GetCheckedHandle ();
}
#endif

[DllImport (Constants.libcLibrary)]
extern static void dispatch_set_target_queue (/* dispatch_object_t */ IntPtr queue, /* dispatch_queue_t */ IntPtr target);
Expand All @@ -149,7 +132,7 @@ public void SetTargetQueue (DispatchQueue queue)
{
// note: null is allowed because DISPATCH_TARGET_QUEUE_DEFAULT is defined as NULL (dispatch/queue.h)
IntPtr q = queue == null ? IntPtr.Zero : queue.Handle;
dispatch_set_target_queue (handle, q);
dispatch_set_target_queue (Handle, q);
}

[DllImport (Constants.libcLibrary)]
Expand All @@ -171,11 +154,10 @@ public DispatchQueue (IntPtr handle) : base (handle, false)
{
}

public DispatchQueue (string label) : base ()
public DispatchQueue (string label)
: base (dispatch_queue_create (label, IntPtr.Zero), true)
{
// Initialized in owned state for the queue.
handle = dispatch_queue_create (label, IntPtr.Zero);
if (handle == IntPtr.Zero)
if (Handle == IntPtr.Zero)
throw new Exception ("Error creating dispatch queue");
}

Expand All @@ -189,9 +171,9 @@ static IntPtr ConcurrentQueue {
}

public DispatchQueue (string label, bool concurrent)
: base (dispatch_queue_create (label, concurrent ? ConcurrentQueue : IntPtr.Zero), true)
{
handle = dispatch_queue_create (label, concurrent ? ConcurrentQueue : IntPtr.Zero);
if (handle == IntPtr.Zero)
if (Handle == IntPtr.Zero)
throw new Exception ("Error creating dispatch queue");
}

Expand All @@ -201,10 +183,7 @@ public DispatchQueue (string label, bool concurrent)

public string Label {
get {
if (handle == IntPtr.Zero)
throw new ObjectDisposedException ("DispatchQueue");

return Marshal.PtrToStringAnsi (dispatch_queue_get_label (handle));
return Marshal.PtrToStringAnsi (dispatch_queue_get_label (GetCheckedHandle ()));
}
}

Expand All @@ -217,14 +196,12 @@ public static string CurrentQueueLabel {

public void Suspend ()
{
Check ();
dispatch_suspend (handle);
dispatch_suspend (GetCheckedHandle ());
}

public void Resume ()
{
Check ();
dispatch_resume (handle);
dispatch_resume (GetCheckedHandle ());
}

[DllImport (Constants.libcLibrary)]
Expand All @@ -238,12 +215,10 @@ public void Resume ()

public IntPtr Context {
get {
Check ();
return dispatch_get_context (handle);
return dispatch_get_context (GetCheckedHandle ());
}
set {
Check ();
dispatch_set_context (handle, value);
dispatch_set_context (GetCheckedHandle (), value);
}
}

Expand Down Expand Up @@ -350,38 +325,38 @@ public void DispatchAsync (Action action)
if (action == null)
throw new ArgumentNullException ("action");

dispatch_async_f (handle, (IntPtr) GCHandle.Alloc (Tuple.Create (action, this)), static_dispatch);
dispatch_async_f (Handle, (IntPtr) GCHandle.Alloc (Tuple.Create (action, this)), static_dispatch);
}

public void DispatchSync (Action action)
{
if (action == null)
throw new ArgumentNullException ("action");

dispatch_sync_f (handle, (IntPtr) GCHandle.Alloc (Tuple.Create (action, this)), static_dispatch);
dispatch_sync_f (Handle, (IntPtr) GCHandle.Alloc (Tuple.Create (action, this)), static_dispatch);
}

public void DispatchBarrierAsync (Action action)
{
if (action == null)
throw new ArgumentNullException ("action");

dispatch_barrier_async_f (handle, (IntPtr) GCHandle.Alloc (Tuple.Create (action, this)), static_dispatch);
dispatch_barrier_async_f (Handle, (IntPtr) GCHandle.Alloc (Tuple.Create (action, this)), static_dispatch);
}

public void DispatchAfter (DispatchTime when, Action action)
{
if (action == null)
throw new ArgumentNullException ("action");

dispatch_after_f (when.Nanoseconds, handle, (IntPtr) GCHandle.Alloc (Tuple.Create (action, this)), static_dispatch);
dispatch_after_f (when.Nanoseconds, Handle, (IntPtr) GCHandle.Alloc (Tuple.Create (action, this)), static_dispatch);
}

public void Submit (Action<int> action, long times)
{
if (action == null)
throw new ArgumentNullException ("action");
dispatch_apply_f ((IntPtr) times, handle, (IntPtr) GCHandle.Alloc (Tuple.Create (action, this)), static_dispatch_iterations);
dispatch_apply_f ((IntPtr) times, Handle, (IntPtr) GCHandle.Alloc (Tuple.Create (action, this)), static_dispatch_iterations);
}

//
Expand Down Expand Up @@ -418,7 +393,7 @@ public override bool Equals (object other)
DispatchQueue o = other as DispatchQueue;
if (o == null)
return false;
return (o.Handle == handle);
return (o.Handle == Handle);
}

public static bool operator == (DispatchQueue left, DispatchQueue right)
Expand All @@ -437,7 +412,7 @@ public override bool Equals (object other)

public override int GetHashCode ()
{
return (int)handle;
return (int) Handle;
}

#if MONOMAC
Expand Down Expand Up @@ -524,8 +499,7 @@ public void DispatchAsync (DispatchQueue queue, Action action)
if (action == null)
throw new ArgumentNullException ("action");

Check ();
dispatch_group_async_f (handle, queue.handle, (IntPtr) GCHandle.Alloc (Tuple.Create (action, queue)), DispatchQueue.static_dispatch);
dispatch_group_async_f (GetCheckedHandle (), queue.Handle, (IntPtr) GCHandle.Alloc (Tuple.Create (action, queue)), DispatchQueue.static_dispatch);
}

public void Notify (DispatchQueue queue, Action action)
Expand All @@ -535,26 +509,22 @@ public void Notify (DispatchQueue queue, Action action)
if (action == null)
throw new ArgumentNullException ("action");

Check ();
dispatch_group_notify_f (handle, queue.handle, (IntPtr) GCHandle.Alloc (Tuple.Create (action, queue)), DispatchQueue.static_dispatch);
dispatch_group_notify_f (GetCheckedHandle (), queue.Handle, (IntPtr) GCHandle.Alloc (Tuple.Create (action, queue)), DispatchQueue.static_dispatch);
}

public void Enter ()
{
Check ();
dispatch_group_enter (handle);
dispatch_group_enter (GetCheckedHandle ());
}

public void Leave ()
{
Check ();
dispatch_group_leave (handle);
dispatch_group_leave (GetCheckedHandle ());
}

public bool Wait (DispatchTime timeout)
{
Check ();
return dispatch_group_wait (handle, timeout.Nanoseconds) == 0;
return dispatch_group_wait (GetCheckedHandle (), timeout.Nanoseconds) == 0;
}

[DllImport (Constants.libcLibrary)]
Expand Down
8 changes: 4 additions & 4 deletions src/CoreFoundation/DispatchData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,14 @@ public static DispatchData FromBuffer (IntPtr buffer, nuint size)
[DllImport (Constants.libcLibrary)]
extern static nuint dispatch_data_get_size (IntPtr handle);

public nuint Size => dispatch_data_get_size (handle);
public nuint Size => dispatch_data_get_size (Handle);

[DllImport (Constants.libcLibrary)]
extern static IntPtr dispatch_data_create_map (IntPtr handle, out IntPtr bufferPtr, out nuint size);

public DispatchData CreateMap (out IntPtr bufferPtr, out nuint size)
{
var nh = dispatch_data_create_map (handle, out bufferPtr, out size);
var nh = dispatch_data_create_map (Handle, out bufferPtr, out size);
return new DispatchData (nh, owns: true);
}

Expand All @@ -112,15 +112,15 @@ public static DispatchData Concat (DispatchData data1, DispatchData data2)
if (data2 == null)
throw new ArgumentNullException (nameof (data2));

return new DispatchData (dispatch_data_create_concat (data1.handle, data2.handle), owns: true);
return new DispatchData (dispatch_data_create_concat (data1.Handle, data2.Handle), owns: true);
}

[DllImport (Constants.libcLibrary)]
extern static IntPtr dispatch_data_create_subrange (IntPtr handle, nuint offset, nuint size);

public DispatchData CreateSubrange (nuint offset, nuint size)
{
return new DispatchData (dispatch_data_create_subrange (handle, offset, size), owns: true);
return new DispatchData (dispatch_data_create_subrange (Handle, offset, size), owns: true);
}
#endif
}
Expand Down
Loading

1 comment on commit f96faaa

@xamarin-release-manager
Copy link
Collaborator

Choose a reason for hiding this comment

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

Jenkins job (on internal Jenkins) succeeded

Build succeeded
API Diff (from stable)
⚠️ API Diff (from PR only) (🔥 breaking changes 🔥)
Generator Diff (no change)
Test run succeeded

Please sign in to comment.