Can I call libxml parser from multiple asynchronous network calls? - iphone

I have a piece of code that uses NSURLConnection to fetch a network resource asynchronously and parse some XML as it streams in. The XML parsing is handled by libxml2 which is available as a framework in the iOS SDK. This works perfectly when I invoke it once, parse the XML and release the resources by calling xmlFreeParserCtxt(ctxt).
My problem is that when I run this same code in multiple threads, all of a sudden i see EXC_BAD_ACCESS pop up which I trace back to the libxml2. Specifically the xmlParserCtxtPtr context which is initialized and used for XML parsing seems to throw the EXC_BAD_ACCESS when I release it after I am done retrieving the resource.
The exception goes away if I do not release this context i.e. call xmlFreeParserCtxt(ctxt).
This leads me to believe that my issues are some how related to libxml framework available in iOS not being thread safe.
Sure enough, I see this when I google the issue:
From: http://xmlsoft.org/threads.html
Starting with 2.4.7, libxml2 makes provisions to ensure that concurrent threads can safely work in parallel parsing different documents. There is however a couple of things to do to ensure it:
* configure the library accordingly using the --with-threads options
* call xmlInitParser() in the "main" thread before using any of the libxml2 API (except possibly selecting a different memory allocator)
So I have two questions:
1.) Is my assumption correct that the version of libxml that I am using is not thread safe and hence causing the issue? Has anyone else seen this?
2.) I know that the iOS bundles libxml2.2.x - would it work if I get libxml2.4.7 and add it to my project? Would that cause any rejections on the app store?
Thanks for your time.

Related

Realm - RJSRealmDelegate.changes_available assert(0) causing crash

We are building a React-Native iOS app that needs to access our realms natively as well as via RN.
We have writing working correctly from our UI and can load the data in our background Swift service, but after the write, The changes_available method in js_realm.cpp is firing which contains assert(0) which is causing the app to crash/hang in debug. What do we need to be doing to prevent that method from firing?
Update: A release was just made (0.11.1) which should prevent this crash from occurring. Note that notifications across bindings have not yet been tested and may not work.
This method gets called when changes are made externally to a Realm from another process or thread. In your case it sounds like writes made from the swift apis are causing this method to get called. The ReactNative binding was written with the assumption that everything would be done from a single thread without considering the use of other language bindings being used simultaneously.
As is the only thing you can to do prevent this is to not make a write in Swift while a Realm is open in JS. One way to do this would be to call Realm.close after every use, although this may perform poorly.
In the near term we can also do a point release to remove the assert(0) - this will prevent the crash/hang, but notifications for changes made in Swift wont work without additional changes. Can't give an estimate of when we can get cross language notifications working properly.

ReleaseHandleFail after upgrading to .net 4.0, possibly related to EntityFramework

I recently upgraded an application from .net 3.5 to 4.0. Since I did that, with debug settings to break on all exceptions enabled, I've been getting a few of these exceptions each time I start a section of the application that connects to a database using the EF. The exact number is variable; sometimes I only get one, others several in rapid succession.
ReleaseHandleFailed was detected Message: A SafeHandle or
CriticalHandle of type
'Microsoft.Win32.SafeHandles.SafeCapiHashHandle' failed to properly
release the handle with value 0x06AD3D08. This usually indicates that
the handle was released incorrectly via another means (such as
extracting the handle using DangerousGetHandle and closing it directly
or building another SafeHandle around it.)
I never got exceptions like this when targeting 3.5. These exceptions don't have any meaningful call stack attached, all I get is [External Code], denying any easy way to localize where they're coming from. The reason I suspect EntityFramework is somehow involved is that one section of the app uses nHiberate instead doesn't generate any of these messages.
To run down other dependencies that might be involved: In all cases, the ORM is talking to an Sql Compact database MS Sync Framework 2.1 is being used to update the local DB from SqlServer. The Entity framework models have been regenerated with the 4.0 framework, and I upgraded the cache DB to v4.0 as well.
Since there's no call stack I'm not sure if these messages fall into the category of "harmless" errors automatically cleaned up internal to the framework; or if there's an exception eater catching them elsewhere in the application.
This is not an exception, it is a Managed Debugging Assistant warning. You might have gone over-board a bit when you changed the settings to "break on all exceptions enabled". Debug + Exceptions, Managed Debugging Assistants node, untick the "ReleaseHandleFailed" warning. It is off by default.
The MDA catches an old bug that's gone undetected for a while in the AesCryptoServiceProvider class. Backgrounder is here.
Judging from your comment, you are about to make a drastic mistake. You do not solve this by avoiding encryption or compromising your dbase connection security. You accidentally turned on an MDA that's normally off. MDAs in general tend to produce false warnings and many of them are turned off by default. The warning is in fact bogus, releasing the handle failed because it was already released. This happens in the finalizer thread, that's why you don't get a stack trace. And thus can't easily find out what code uses the class in the first place.
The proper way to fix it is to use the Debug + Exceptions dialog properly. Fix the problem you created by clicking the Reset All button. Then click only the Thrown checkbox for Common Language Runtime exceptions. That's what you are trying to debug.

Faulting thread stack-trace using IDebugControl::GetStackTrace

I have a minidump of crashed application and I would like to analyse it using DbgEng in my own library. Does anyone now how can I get the stacktrace of the thread that caused the program crash using IDebugControl::GetStackTrace?
I appreciate any kind of help
Thx
Depending on how the crash dump was generated, it might be using embedded contexts. Use the IDebugControl4 interface which gives you access to the GetStoredEventInformation and GetContextStackTrace methods. If GetStoredEventInformation fails, you can fall back on the GetStackTrace method.
The solution is described in this article http://blogs.msdn.com/b/joshpoley/archive/2008/11/10/minidumps-and-bad-stacks.aspx

How to sync CoreData and a REST web service asynchronously and the same time properly propagate any REST errors into the UI

Hey, I'm working on the model layer for our app here.
Some of the requirements are like this:
It should work on iPhone OS 3.0+.
The source of our data is a RESTful Rails application.
We should cache the data locally using Core Data.
The client code (our UI controllers) should have as little knowledge about any network stuff as possible and should query/update the model with the Core Data API.
I've checked out the WWDC10 Session 117 on Building a Server-driven User Experience, spent some time checking out the Objective Resource, Core Resource, and RestfulCoreData frameworks.
The Objective Resource framework doesn't talk to Core Data on its own and is merely a REST client implementation. The Core Resource and RestfulCoreData all assume you talk to Core Data in your code and they solve all the nuts and bolts in the background on the model layer.
All looks okay so far and initially I though either Core Resource or RestfulCoreData will cover all of the above requirements, but... There's a couple of things none of them seemingly happen to solve correctly:
The main thread should not be blocked while saving local updates to the server.
If the saving operation fails the error should be propagated to the UI and no changes should be saved to the local Core Data storage.
Core Resource happens to issue all of its requests to the server when you call - (BOOL)save:(NSError **)error on your Managed Object Context and therefore is able to provide a correct NSError instance of the underlying requests to the server fail somehow. But it blocks the calling thread until the save operation finishes. FAIL.
RestfulCoreData keeps your -save: calls intact and doesn't introduce any additional waiting time for the client thread. It merely watches out for the NSManagedObjectContextDidSaveNotification and then issues the corresponding requests to the server in the notification handler. But this way the -save: call always completes successfully (well, given Core Data is okay with the saved changes) and the client code that actually called it has no way to know the save might have failed to propagate to the server because of some 404 or 421 or whatever server-side error occurred. And even more, the local storage becomes to have the data updated, but the server never knows about the changes. FAIL.
So, I'm looking for a possible solution / common practices in dealing with all these problems:
I don't want the calling thread to block on each -save: call while the network requests happen.
I want to somehow get notifications in the UI that some sync operation went wrong.
I want the actual Core Data save fail as well if the server requests fail.
Any ideas?
You should really take a look at RestKit (http://restkit.org) for this use case. It is designed to solve the problems of modeling and syncing remote JSON resources to a local Core Data backed cache. It supports an offline mode for working entirely from the cache when there is no network available. All syncing occurs on a background thread (network access, payload parsing, and managed object context merging) and there is a rich set of delegate methods so you can tell what is going on.
There are three basic components:
The UI Action and persisting the change to CoreData
Persisting that change up to the server
Refreshing the UI with the response of the server
An NSOperation + NSOperationQueue will help keep the network requests orderly. A delegate protocol will help your UI classes understand what state the network requests are in, something like:
#protocol NetworkOperationDelegate
- (void)operation:(NSOperation *)op willSendRequest:(NSURLRequest *)request forChangedEntityWithId:(NSManagedObjectID *)entity;
- (void)operation:(NSOperation *)op didSuccessfullySendRequest:(NSURLRequest *)request forChangedEntityWithId:(NSManagedObjectID *)entity;
- (void)operation:(NSOperation *)op encounteredAnError:(NSError *)error afterSendingRequest:(NSURLRequest *)request forChangedEntityWithId:(NSManagedObjectID *)entity;
#end
The protocol format will of course depend on your specific use case but essentially what you're creating is a mechanism by which changes can be "pushed" up to your server.
Next there's the UI loop to consider, to keep your code clean it would be nice to call save: and have the changes automatically pushed up to the server. You can use NSManagedObjectContextDidSave notifications for this.
- (void)managedObjectContextDidSave:(NSNotification *)saveNotification {
NSArray *inserted = [[saveNotification userInfo] valueForKey:NSInsertedObjects];
for (NSManagedObject *obj in inserted) {
//create a new NSOperation for this entity which will invoke the appropraite rest api
//add to operation queue
}
//do the same thing for deleted and updated objects
}
The computational overhead for inserting the network operations should be rather low, however if it creates a noticeable lag on the UI you could simply grab the entity ids out of the save notification and create the operations on a background thread.
If your REST API supports batching, you could even send the entire array across at once and then notify you UI that multiple entities were synchronized.
The only issue I foresee, and for which there is no "real" solution is that the user will not want to wait for their changes to be pushed to the server to be allowed to make more changes. The only good paradigm I have come across is that you allow the user to keep editing objects, and batch their edits together when appropriate, i.e. you do not push on every save notification.
This becomes a sync problem and not one easy to solve. Here's what I'd do: In your iPhone UI use one context and then using another context (and another thread) download the data from your web service. Once it's all there go through the sync/importing processes recommended below and then refresh your UI after everything has imported properly. If things go bad while accessing the network, just roll back the changes in the non UI context. It's a bunch of work, but I think it's the best way to approach it.
Core Data: Efficiently Importing Data
Core Data: Change Management
Core Data: Multi-Threading with Core Data
You need a callback function that's going to run on the other thread (the one where actual server interaction happens) and then put the result code/error info a semi-global data which will be periodically checked by UI thread. Make sure that the wirting of the number that serves as the flag is atomic or you are going to have a race condition - say if your error response is 32 bytes you need an int (whihc should have atomic acces) and then you keep that int in the off/false/not-ready state till your larger data block has been written and only then write "true" to flip the switch so to speak.
For the correlated saving on the client side you have to either just keep that data and not save it till you get OK from the server of make sure that you have a kinnf of rollback option - say a way to delete is server failed.
Beware that it's never going to be 100% safe unless you do full 2-phase commit procedure (client save or delete can fail after the signal from the server server) but that's going to cost you 2 trips to the server at the very least (might cost you 4 if your sole rollback option is delete).
Ideally, you'd do the whole blocking version of the operation on a separate thread but you'd need 4.0 for that.

SQLite on iPhone - Techniques for tracking down multithreading-related bugs

I'm working with an Objective-C wrapper around SQLite that I didn't write, and documentation is sparse...
It's not FMDB. The people writing this wrapper weren't aware of FMDB when writing this code.
It seems that the code is suffering from a bug where database connections are being accessed from multiple threads -- which according to the SQLite documentation won't work if the if SQLite is compiled with SQLITE_THREADSAFE 2.
I have tested the libsqlite3.dylib provided as part of the iPhone SDK and seen that it is compiled in this manner, using the sqlite_threadsafe() routine.
Using the provided sqlite library, the code regularly hits SQLITE_BUSY and SQLITE_LOCKED return codes when performing routines.
To combat this, I added some code to wait a couple of milliseconds and try again, with a maximum retry count of 50. The code didn't contain any retry logic prior to this.
Now when a sqlite call returns SQLITE_BUSY or SQLITE_LOCKED, the retry loop is invoked and the retry returns SQLITE_MISUSE. Not good.
Grasping at straws, I replaced the provided sqlite library with a version compiled by myself setting SQLITE_THREADSAFE to 1 - which according to the documentation means sqlite is safe to be used in a multithreaded environment, effectively serialising all of the operations. It incurs a performance hit, that which I haven't measured, but it ridded the app of the SQLITE_MISUSE happening and seemed to not need the retry logic as it never hit a busy or locked state.
What I would rather do is fix the problem of accessing a single db connection from multiple threads, but I can't for the life of me find where it's occurring.
So if anyone has any tips on locating multithreaded bugs I would be extremely appreciative.
Thanks in advance.
I haven't tested this to see if it works, but you could try wrapping access to the db connection in a function and then using Instruments to log accesses to that function which, IIRC, should let you get a thread ID and a stack trace. That should give you a bit of a handle on where it's coming from. Alternatively you could just set a breakpoint on it but that might take a bit longer.