Bug 8437 - Using CFProxy might not be thread-safe
Summary: Using CFProxy might not be thread-safe
Alias: None
Product: iOS
Classification: Xamarin
Component: Xamarin.iOS.dll ()
Version: 6.0.x
Hardware: PC Mac OS
: --- normal
Target Milestone: Untriaged
Assignee: Sebastien Pouliot
: 8407 ()
Depends on:
Reported: 2012-11-15 15:43 UTC by Sebastien Pouliot
Modified: 2013-12-05 18:34 UTC (History)
4 users (show)

Is this bug a regression?: ---
Last known good build:

CFProxy crash (67.74 KB, application/octet-stream)
2012-11-15 17:07 UTC, Dan Abramov

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Sebastien Pouliot 2012-11-15 15:43:06 UTC
Spinoff of bug #8407
Comment 1 Dan Abramov 2012-11-15 17:03:33 UTC
Now I can confirm that replacing Proxy with GlobalProxySelection.GetEmptyWebProxy() solved the issue: I haven't had a crash in 24 hours. So it's definitely NOT thread safe.
Comment 2 Dan Abramov 2012-11-15 17:07:15 UTC
Created attachment 2952 [details]
CFProxy crash
Comment 3 Martin Baulig 2012-11-16 16:13:01 UTC
I wouldn't be too surprised if the underlying native API that CFProxy is calling is not thread-safe.  We may have to put some lock()'s around that code.
Comment 4 Sebastien Pouliot 2012-11-20 09:26:45 UTC
Dan, how common was the crash ?

Using an iOS device (iPad3), release build, using TPL (Task.Factory.StartNew) I can process 1000 Uri on the same code path without a crash. Am I just lucky ?

If it's more common that 1 out of 1000 can you share a bit of your code ? Thanks
Comment 5 Dan Abramov 2012-11-20 10:52:24 UTC
I'm not sure how many requests there were at the time and it seemed to happen randomly once in 10 minutes during very heavy usage.

What I mean by heavy?

We had a collection control with a pool of recyclable views, similar to UICollectionView, 12 items on one page. We used DropNet via RestSharp to query for DropBox thumbnails with GetThumbnailTask.

The version of DropNet we're using is almost identical to DropNet master, except that I added CancellationToken support: https://github.com/stampsy/DropNet/commit/d0c64df0782880beba5ca65f863777afdfd12390

We used a custom scheduler to artificially limit the number of concurrent requests. This gave a great performance boost when task cancellation actually aborted underlying requests but as you know this frequently crashed on the device. Still, performance was better with the custom scheduler than without it.

To reproduce the crash, I had to constantly swipe pages back and forth, sometimes really fast, and sometimes waiting for a second or two. I would get a crash within fifteen minutes of scrolling.

Because I couldn't control the request threads (RestSharp uses HttpWebRequest.BeginGetResponse), I'm not sure how many actual threads there were—only that I had 6 concurrent Tasks that prevented more requests from being made. But that 6-task queue was constantly recycling because, as I was scrolling back and forth, tasks from previous pages got cancelled.

If this is still unclear, maybe we can schedule a chat? I'm hesitant to sharing the source code, as it would be hard to separate it from the app and the libraries like DropNet.
Comment 6 Sebastien Pouliot 2012-11-20 14:52:32 UTC
My original test case was not so heavy - but, sadly, making it heavier did not help to reproduce your crash.

I made a version that used many threads calling the same code (that crashed) without results*. Another version, with less "live" threads, did 1000000 calls (took more than 2 hours) without any crash.

* it crashed differently (out of memory) when it got over live 200 threads
Comment 8 Dan Abramov 2012-11-20 15:09:01 UTC
It is very possible the device I was using has been jailbroken, does this change anything?
Also, I just checked in the crash log that it was an iPad 2.
Comment 9 Sebastien Pouliot 2012-11-20 15:15:30 UTC
It's very difficult to say what jailbreaking might (or might not) do. If you have a non-jailbroken device then it's worth testing on it too.

I do not have an iPad 2 but I can try it on my iPad 1 to see if there's any difference (even if it's a single core).

I forgot to ask but do you have any proxy settings ? I assumed not (and I have none) and runs with the default "empty" proxy settings provided by iOS.
Comment 10 Dan Abramov 2012-11-20 15:20:03 UTC
I just checked the device—no, it's not jailbroken.
Proxy settings were empty ("Off").

Unfortunately I can't test that code right now because that part is in the middle of a rewrite. I'll be able to get back to you to test that version in a few days.
Comment 11 Sebastien Pouliot 2012-11-20 16:12:40 UTC
No problem, I'll continue to use my test case on my other devices. 
Also are you using LLVM (your stack trace suggest that) ?
Comment 12 GouriKumari 2013-07-08 18:39:45 UTC
*** Bug 8407 has been marked as a duplicate of this bug. ***
Comment 13 PJ 2013-11-19 17:04:01 UTC
This bug has been in the NEEDINFO state with no changes for the last 90 days. Can we put this back into the NEW or CONFIRMED state, or are we still awaiting response?

If there is no change in the status of this bug over the next two weeks, this bug will be marked as NORESPONSE.
Comment 14 PJ 2013-12-05 18:34:02 UTC
This bug has not been changed from the NEEDINFO state since my previous comment, marking as RESOLVED NORESPONSE.

Please feel free to REOPEN this bug at any time if you are still experiencing the issue. Please add the requested information and set the bug back to the NEW (or CONFIRMED) state.