public void NSAutoreleasePoolInThreadPool() { var count = 100; var counter = new CountdownEvent(count); var obj = new NSObject(); for (int i = 0; i < count; i++) { ThreadPool.QueueUserWorkItem((v) => { obj.DangerousRetain().DangerousAutorelease(); counter.Signal(); }); } Assert.IsTrue(counter.Wait(TimeSpan.FromSeconds(5)), "timed out"); // there is a race condition here: we don't necessarily know when the // threadpool's autorelease pools are freed (in theory we can have X // threadpool threads stopped just after the 'counter.Signal' line, // before unwinding to the autorelease pool's dispose frame). So // assert that the retain count has decreased, but not that it has // decreased to 1 var max_iterations = 100; var iterations = 0; while ((long)obj.RetainCount > (long)count / 2 && iterations++ < max_iterations) { Thread.Sleep(100); } Assert.That(obj.RetainCount, Is.Not.GreaterThan((nuint)(count / 2)), "RC. Iterations: " + iterations); obj.Dispose(); }
public void NSAutoreleasePoolInThread() { var count = 10; var threads = new Thread [count]; var obj = new NSObject(); for (int i = 0; i < count; i++) { threads [i] = new Thread((v) => { obj.DangerousRetain().DangerousAutorelease(); }) { Name = $"NSAutoreleasePoolInThread #{i}", IsBackground = true, }; threads [i].Start(); } for (var i = 0; i < count; i++) { Assert.IsTrue(threads [i].Join(TimeSpan.FromSeconds(1)), $"Thread #{i}"); } // Strangely enough there seems to be a race condition here, not all threads will necessarily // have completed the autorelease by this point. Some should have though, so assert that the object // was released on at least half the threads. Assert.That((int)obj.RetainCount, Is.LessThan(count / 2), "RC"); obj.Dispose(); }
static void ExecutePacCallback(IntPtr client, IntPtr proxyList, IntPtr error) { // grab the required structure and set the data, according apple docs: // client // The client reference originally passed in the clientContext parameter of the // CFNetworkExecuteProxyAutoConfigurationScript or CFNetworkExecuteProxyAutoConfigurationURL call // that triggered this callback. // Well, that is NOT TRUE, the client passed is the client.Info pointer not the client. var pacCbData = (PACProxyCallbackData)Marshal.PtrToStructure(client, typeof(PACProxyCallbackData)); // make sure is not released, will be released by the parsing method. if (proxyList != IntPtr.Zero) { CFObject.CFRetain(proxyList); pacCbData.ProxyListPtr = proxyList; } if (error != IntPtr.Zero) { NSObject.DangerousRetain(error); pacCbData.ErrorPtr = error; } // stop the CFRunLoop var runLoop = new CFRunLoop(pacCbData.CFRunLoopPtr); Marshal.StructureToPtr(pacCbData, client, false); runLoop.Stop(); }
static void AddStyles() { Style.Add <Main>(null, ctl => ctl.ClientChanged += (sender, e) => { if (NSProcessInfo.ProcessInfo.RespondsToSelector(Selector.FromHandle(selBeginActivity))) { // ensure we don't go to sleep when the server (or client) is running! (10.9) if (activityToken != null) { void_objc_msgSend_IntPtr(NSProcessInfo.ProcessInfo.Handle, selEndActivity, activityToken.Handle); activityToken.DangerousRelease(); activityToken = null; } bool enabled = ctl.Client != null; if (enabled) { var token = IntPtr_objc_msgSend_Int64_IntPtr(NSProcessInfo.ProcessInfo.Handle, selBeginActivity, (Int64)NSActivityOptions.UserInitiated, ActivityReason.Handle); if (token != IntPtr.Zero) { activityToken = new NSObject(token); activityToken.DangerousRetain(); } } } }); Style.Add <FormHandler>("main", handler => handler.Control.CollectionBehavior |= NSWindowCollectionBehavior.FullScreenPrimary); /*control.WillUseFullScreenPresentationOptions = (window, proposedOptions) => { * return NSApplicationPresentationOptions.FullScreen | NSApplicationPresentationOptions.AutoHideToolbar | NSApplicationPresentationOptions.AutoHideMenuBar | NSApplicationPresentationOptions.AutoHideDock; * };*/ Style.Add <ListBoxHandler>("fileList", handler => { handler.Scroll.BorderType = NSBorderType.NoBorder; handler.Control.SelectionHighlightStyle = NSTableViewSelectionHighlightStyle.SourceList; }); Style.Add <ApplicationHandler>("application", handler => handler.EnableFullScreen()); Style.Add <ScrollableHandler>("viewerPane", handler => { if (handler.Control.RespondsToSelector(new Selector("setScrollerKnobStyle:"))) { handler.Control.ScrollerKnobStyle = NSScrollerKnobStyle.Light; } }); Style.Add <ToolBarHandler>(null, handler => { handler.Control.DisplayMode = NSToolbarDisplayMode.Icon; }); Style.Add <ButtonToolItemHandler>(null, handler => { handler.UseStandardButton(false); }); Style.Add <CheckToolItemHandler>(null, handler => { handler.Control.MaxSize = new CGSize(16, 16); handler.Tint = Colors.Gray; }); }