コード例 #1
0
ファイル: CFSocket.cs プロジェクト: tondat/xamarin-macios
        internal CFSocket(CFSocketNativeHandle sock)
        {
            var cbTypes = CFSocketCallBackType.DataCallBack | CFSocketCallBackType.WriteCallBack;

            gch = GCHandle.Alloc(this);
            var ctx = new CFStreamClientContext();

            ctx.Info = GCHandle.ToIntPtr(gch);

            var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CFStreamClientContext)));

            try {
                Marshal.StructureToPtr(ctx, ptr, false);
                handle = CFSocketCreateWithNative(
                    IntPtr.Zero, sock, (nuint)(ulong)cbTypes, OnCallback, ptr);
            } finally {
                Marshal.FreeHGlobal(ptr);
            }

            if (handle == IntPtr.Zero)
            {
                throw new CFSocketException(CFSocketError.Error);
            }

            var source = new CFRunLoopSource(CFSocketCreateRunLoopSource(IntPtr.Zero, handle, 0));
            var loop   = CFRunLoop.Current;

            loop.AddSource(source, CFRunLoop.ModeDefault);
        }
コード例 #2
0
ファイル: CFSocket.cs プロジェクト: tondat/xamarin-macios
        CFSocket(int family, int type, int proto, CFRunLoop loop)
        {
            var cbTypes = CFSocketCallBackType.DataCallBack | CFSocketCallBackType.ConnectCallBack;

            gch = GCHandle.Alloc(this);
            var ctx = new CFStreamClientContext();

            ctx.Info = GCHandle.ToIntPtr(gch);

            var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(CFStreamClientContext)));

            try {
                Marshal.StructureToPtr(ctx, ptr, false);
                handle = CFSocketCreate(
                    IntPtr.Zero, family, type, proto, (nuint)(ulong)cbTypes, OnCallback, ptr);
            } finally {
                Marshal.FreeHGlobal(ptr);
            }

            if (handle == IntPtr.Zero)
            {
                throw new CFSocketException(CFSocketError.Error);
            }
            gch = GCHandle.Alloc(this);

            var source = new CFRunLoopSource(CFSocketCreateRunLoopSource(IntPtr.Zero, handle, 0));

            loop.AddSource(source, CFRunLoop.ModeDefault);
        }
コード例 #3
0
ファイル: CFSocket.cs プロジェクト: tondat/xamarin-macios
        CFSocket(IntPtr handle)
        {
            this.handle = handle;
            gch         = GCHandle.Alloc(this);

            var source = new CFRunLoopSource(CFSocketCreateRunLoopSource(IntPtr.Zero, handle, 0));
            var loop   = CFRunLoop.Current;

            loop.AddSource(source, CFRunLoop.ModeDefault);
        }
コード例 #4
0
        public void RemoveSource(CFRunLoopSource source, NSString mode)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }
            if (mode == null)
            {
                throw new ArgumentNullException("mode");
            }

            CFRunLoopRemoveSource(handle, source.Handle, mode.Handle);
        }
コード例 #5
0
        public bool ContainsSource(CFRunLoopSource source, NSString mode)
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }
            if (mode == null)
            {
                throw new ArgumentNullException("mode");
            }

            return(CFRunLoopContainsSource(handle, source.Handle, mode.Handle));
        }
コード例 #6
0
ファイル: CFRunLoop.cs プロジェクト: cwensley/xamarin-macios
        public void RemoveSource(CFRunLoopSource source, NSString mode)
        {
            if (source is null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (mode is null)
            {
                throw new ArgumentNullException(nameof(mode));
            }

            CFRunLoopRemoveSource(Handle, source.Handle, mode.Handle);
        }
コード例 #7
0
ファイル: CFRunLoop.cs プロジェクト: cwensley/xamarin-macios
        public bool ContainsSource(CFRunLoopSource source, NSString mode)
        {
            if (source is null)
            {
                throw new ArgumentNullException(nameof(source));
            }
            if (mode is null)
            {
                throw new ArgumentNullException(nameof(mode));
            }

            return(CFRunLoopContainsSource(Handle, source.Handle, mode.Handle));
        }
コード例 #8
0
ファイル: CFSocket.cs プロジェクト: cwensley/xamarin-macios
        CFSocket(NativeHandle handle, bool owns)
            : base(handle, owns)
        {
            gch = GCHandle.Alloc(this);

            try {
                var source = new CFRunLoopSource(CFSocketCreateRunLoopSource(IntPtr.Zero, handle, 0), true);
                var loop   = CFRunLoop.Current;
                loop.AddSource(source, CFRunLoop.ModeDefault);
            } catch {
                gch.Free();
                throw;
            }
        }
コード例 #9
0
ファイル: CFRunLoop.cs プロジェクト: ye-man/xamarin-macios
        public bool RemoveSource(CFRunLoopSource source, NSString mode)
#endif
        {
            if (source == null)
            {
                throw new ArgumentNullException("source");
            }
            if (mode == null)
            {
                throw new ArgumentNullException("mode");
            }

            CFRunLoopRemoveSource(handle, source.Handle, mode.Handle);
#if !XAMCORE_2_0
            return(true);
#endif
        }
コード例 #10
0
ファイル: CFSocket.cs プロジェクト: cwensley/xamarin-macios
        CFSocket(int family, int type, int proto, CFRunLoop loop)
        {
            var cbTypes = CFSocketCallBackType.DataCallBack | CFSocketCallBackType.ConnectCallBack;

            gch = GCHandle.Alloc(this);
            try {
                var ctx = new CFStreamClientContext();
                ctx.Info = GCHandle.ToIntPtr(gch);

                var handle = CFSocketCreate(IntPtr.Zero, family, type, proto, (nuint)(ulong)cbTypes, OnCallback, ref ctx);
                InitializeHandle(handle);

                var source = new CFRunLoopSource(CFSocketCreateRunLoopSource(IntPtr.Zero, handle, 0), true);
                loop.AddSource(source, CFRunLoop.ModeDefault);
            } catch {
                gch.Free();
                throw;
            }
        }
コード例 #11
0
ファイル: CFSocket.cs プロジェクト: cwensley/xamarin-macios
        CFSocket(CFSocketNativeHandle sock)
        {
            var cbTypes = CFSocketCallBackType.DataCallBack | CFSocketCallBackType.WriteCallBack;

            gch = GCHandle.Alloc(this);
            try {
                var ctx = new CFStreamClientContext();
                ctx.Info = GCHandle.ToIntPtr(gch);

                var handle = CFSocketCreateWithNative(IntPtr.Zero, sock, (nuint)(ulong)cbTypes, OnCallback, ref ctx);
                InitializeHandle(handle);

                var source = new CFRunLoopSource(CFSocketCreateRunLoopSource(IntPtr.Zero, handle, 0), true);
                var loop   = CFRunLoop.Current;
                loop.AddSource(source, CFRunLoop.ModeDefault);
            } catch {
                gch.Free();
                throw;
            }
        }
コード例 #12
0
        static CFProxy[] ExecutePacCFRunLoopSourceBlocking(CreatePACCFRunLoopSource factory, out NSError outError)
        {
            var runLoop = CFRunLoop.Current;

            outError = null;

            // build a struct that will have all the needed info for the callback
            var pacCbData = new PACProxyCallbackData();

            pacCbData.CFRunLoopPtr = runLoop.Handle;
            var pacDataPtr = Marshal.AllocHGlobal(Marshal.SizeOf(pacCbData));

            try {
                Marshal.StructureToPtr(pacCbData, pacDataPtr, false);

                var clientContext = new CFStreamClientContext();
                clientContext.Info = pacDataPtr;

                using (var loopSource = new CFRunLoopSource(factory(ExecutePacCallback, ref clientContext)))
                    using (var mode = new NSString("Xamarin.iOS.Proxy")) {
                        runLoop.AddSource(loopSource, mode);
                        runLoop.RunInMode(mode, double.MaxValue, false);
                        runLoop.RemoveSource(loopSource, mode);
                    }
                pacCbData = (PACProxyCallbackData)Marshal.PtrToStructure(pacDataPtr, typeof(PACProxyCallbackData));
                // get data from the struct
                outError = pacCbData.Error;
                return(pacCbData.ProxyList);
            } finally {
                if (pacCbData.ProxyListPtr != IntPtr.Zero)
                {
                    CFObject.CFRelease(pacCbData.ProxyListPtr);
                }
                if (pacCbData.ErrorPtr != IntPtr.Zero)
                {
                    NSObject.DangerousRelease(pacCbData.ErrorPtr);
                }
                Marshal.FreeHGlobal(pacDataPtr);
            }
        }
コード例 #13
0
ファイル: CFRunLoop.cs プロジェクト: ye-man/xamarin-macios
 public void RemoveSource(CFRunLoopSource source, NSString mode)
コード例 #14
0
        static async Task <(CFProxy[] proxies, NSError error)> ExecutePacCFRunLoopSourceAsync(CreatePACCFRunLoopSource factory, CancellationToken cancellationToken)
        {
            CFProxy[] proxies  = null;
            NSError   outError = null;

            if (cancellationToken.IsCancellationRequested)
            {
                throw new OperationCanceledException("Operation was cancelled.");
            }

            await Task.Run(() => {
                // we need the runloop of THIS thread, so it is important to get it in the correct context
                var runLoop = CFRunLoop.Current;

                // build a struct that will have all the needed info for the callback
                var pacCbData          = new PACProxyCallbackData();
                pacCbData.CFRunLoopPtr = runLoop.Handle;
                var pacDataPtr         = Marshal.AllocHGlobal(Marshal.SizeOf(pacCbData));
                try {
                    Marshal.StructureToPtr(pacCbData, pacDataPtr, false);

                    var clientContext  = new CFStreamClientContext();
                    clientContext.Info = pacDataPtr;

                    using (var loopSource = new CFRunLoopSource(factory(ExecutePacCallback, ref clientContext)))
                        using (var mode = new NSString("Xamarin.iOS.Proxy")) {
                            if (cancellationToken.IsCancellationRequested)
                            {
                                throw new OperationCanceledException("Operation was cancelled.");
                            }

                            cancellationToken.Register(() => {
                                //if user cancels, we invalidte the source, stop the runloop and remove the source
                                loopSource.Invalidate();
                                runLoop.RemoveSource(loopSource, mode);
                                runLoop.Stop();
                            });
                            runLoop.AddSource(loopSource, mode);
                            // blocks until stop is called, will be done in the cb set previously
                            runLoop.RunInMode(mode, double.MaxValue, false);
                            // does not raise an error if source is not longer present, so no need to worry
                            runLoop.RemoveSource(loopSource, mode);
                        }

                    if (cancellationToken.IsCancellationRequested)
                    {
                        throw new OperationCanceledException("Operation was cancelled.");
                    }

                    pacCbData = (PACProxyCallbackData)Marshal.PtrToStructure(pacDataPtr, typeof(PACProxyCallbackData));
                    // get data from the struct
                    proxies  = pacCbData.ProxyList;
                    outError = pacCbData.Error;
                } finally {
                    // clean resources
                    if (pacCbData.ProxyListPtr != IntPtr.Zero)
                    {
                        CFObject.CFRelease(pacCbData.ProxyListPtr);
                    }
                    if (pacCbData.ErrorPtr != IntPtr.Zero)
                    {
                        NSObject.DangerousRelease(pacCbData.ErrorPtr);
                    }
                    Marshal.FreeHGlobal(pacDataPtr);
                }
            }, cancellationToken).ConfigureAwait(false);

            if (cancellationToken.IsCancellationRequested)
            {
                throw new OperationCanceledException("Operation was cancelled.");
            }
            return(proxies : proxies, error : outError);
        }