What may cause wxFrame::Destroy() to not to destroy anything? - wxwidgets

I'm absolutely aware of the fact that there is no clear solution available for my question, that's why I'm NOT asking why it does not work but what the intended behaviour is/how the current implementation is specified to work:
I have a wxFrame-derived class with a lot of sub-GUI-elements. On close wxFrame::Destroy() is called and I end up not only in destructor of my wxFrame-derived class but also in destructors of all these sub-elements. In this case all my windows are closed and the application exits properly.
Now under some condition this does not work: I can step throug wxFrame::Destroy(), it is doing the same as usual but afterwards no desctructor is called, the application stays alive and visible. I can try to close/call wxFrame::Destroy() several times in this situation, the result is always the same, the application stays alive and all windows are still visible and usable.
I personally would guess, it has to do with one of my sub-elements but I have no idea, which one/what could cause this behaviour.
So my question: how is wxFrame::Destroy() intendend to work, under what conditions would it reject such a call and would not destroy the related wxFrame?

wxFrame::Destroy() doesn't destroy the window immediately, it just marks it for deletion which will actually happen during the next message loop iteration, after all the pending messages are processed (this is important as some of these pending messages might have handlers referencing the frame about to be deleted). So the most common explanation of a problem like this one you're describing is that there is something generating events faster than they can be processed and so the message loop never becomes idle.
For example, in the older versions of wxWidgets, this could happen with wxEVT_PAINT events under MSW if you didn't repaint all the windows properly, i.e. didn't create wxPaintDC in your paint handler. wxWidgets 3 have added some workarounds which prevent this exact scenario from occurring, but something slightly more complicated could still happen.
To debug this, it can be useful to run Spy++ application and check if you see a never-ending stream of Windows messages to your application windows.

Related

What high level synchronisation construct should be used for thread safe single shot method?

I have a situation where a session of background processing can finish by timing out, user asynchronously cancelling or the session completing. Any of those completion events can run a single shot completion method. The completion method must only be run once. Assume that the session is an instance of an object so any synchronisation must use instance constructs.
Currently I'm using an Atomic Compare and Swap operation on a completion state variable so that each event can test and set the completion state when it runs. The first completion event to fire gets to set the completed state and run the single shot method and the remaining events fail. This works nicely.
However I can't help feeling that I should be able to do this in a higher level way. I tried using a Lock object (NSLock as I'm writing this with Cocoa) but then got a warning that I was releasing a lock that was still in the locked state. This is what I want of course. The lock gets locked once and never unlocked but I was afraid that system resources representing the lock might get leaked.
Anyway, I'm just interested as to whether anyone knows of a more high level way to achieve a single shot method like this.
sample code for any of the completion events:
if(OSAtomicCompareAndSwapInt(0, 1, &completed))
{
self.completionCallback();
}
Doing a CAS is almost certainly the right thing to do. Locks are not designed for what you need, they are likely to be much more expensive and are semantically a poor match anyway -- the completion is not "locked". It is "done". A boolean flag is the right representation, and doing a CAS ensures that it is manipulated safely in concurrent scenarios. In C++, I'd use std::atomic_flag for this, maybe check whether Cocoa has anything similar (this just wraps the CAS in a nicer interface, so that you never accidentally use a non-CAS test on the variable, which would be racy).
(edit: in pthreads, there's a function called pthread_once which does what you want, but I wouldn't know about Cocoa; the pthread_once interface is quite unwieldy anyway, in my opinion...)

How dangerous is it to use runModalForWindow from multiple threads?

I have a memory corruption error (I suspect), which is resulting in a program crash after specific UI actions. This is a Cocoa Objective-C application and does not use GC.
After many hours of debugging, I found a possible reason for the crash:
DiscSelectPopup *popupSelect = [[DiscSelectPopup alloc] initWithDataList:dataList count:count];
NSInteger result = [NSApp runModalForWindow:popupSelect.window];
The above popup routine is executed from a secondary thread. This thread is created and started every time the user clicks on a button. So, we can have several modal popup show up simultaneously.
When I run the program in debug mode with MallocStackLogging=1 and MallocStackLoggingNoCompact=1, it prints a malloc error log message at the runModalForWindow: call (but not always).
malloc: *** error for object 0xbc65840: double free
.....
malloc: *** error for object 0xbc547e0: pointer being freed was not allocated
Is it really bad to use runModalForWindow: from a secondary thread?
Could it be the reason for the crash?
Is it really bad to use runModalForWindow from the secondary thread?
Yes. UI stuff needs to happen on the main thread.
You also shouldn't use runModalForWindow: unless you specifically want to block all of the other windows in your application (essentially freezing your app except for that window). Just show the window. If you want to block a specific window (or your app is single-window), begin it as a sheet.
Edit: Looking again at the question, this caught my eye:
The above popup routine is executed from a secondary thread.
Don't do that. To show a window, just show it. Receive the action message from the button on the main thread, and then do only the actual work—if anything—on a secondary thread.
Note that showing the window will not block any other windows or anything else you're doing unless you specifically make it do so (i.e., use runModalForWindow:). If you show the window in the normal way, all your windows continue to work normally. Any timers and observers and similar things you've scheduled on the main thread also continue to work. You don't need to create threads or do anything else special for this; it all just works by default.
If the work that you'll eventually do may take a non-trivial amount of time, then you should put that on a secondary thread, only when it comes time to do it. You should also look into whether or not it'd be easier or better to construct as operation objects or blocks than as raw threads. It probably will.
Using valgrind memcheck, I concluded that the secondary thread runModalForWindow: calls are not directly connected with the memory corruption problem.
Yes, it is bad coding to manipulate UI components from non-main threads but such behavior alone cannot crash the program.
The malloc error message in the question was due to the mistakenly double released popup window object.
By the way, real cause of the memory corruption was the mismatched malloc/free call (freeing not malloced memory pointer).

What does NSManagedContext reset do?

Here's my scenario: I have a thread running heavy calculations, saving the results via core data at the end. I have the thread set up with it's own autorelease pool and it's own NSManagedContext created within the thread. The user can change the inputs to the calculation on the main thread, in which case the calculation thread is terminated (via regular checks of a NSLocked variable) and relaunched with the new inputs. Everything is working fine here.
For performance reasons, the calculation thread doesn't have an undo manager and there is only one context save at the very end. If a termination command is detected I don't want to save the results. Right now I'm just skipping the context save and releasing it, which seems to work fine.
I noticed, however, that there's a reset method for NSManagedContext. Apple's documentation on this method isn't very helpful to me. It simply states that it returns the receiver's contents to it's base state and that all the receiver's managed objects are "forgotten".
What does that mean? Is it the equivalent to reverting to the last saved version? Is an undo manager required for proper operation of this method? Any reason I should use this method instead of what I'm doing now?
It sounds like you are using the context to cache changes independent of the context on the main thread, and if you don't want those changes to be recorded, you just throw them out by deleting the "local" context. This is good enough for the scenario you are describing. -reset might be useful if you didn't want to relaunch the background thread, but just start over using the same thread (and context), but with new inputs. Since you launch a new thread (thus creating a new NSManagedObjectContext on it), -reset is probably not very useful for you in this scenario. You already pretty much doing it as Apple recommends in several of their sample codes.

Should my block based methods return on the main thread or not when creating an iOS cloud integration framework?

I am in the middle of creating a cloud integration framework for iOS. We allow you to save, query, count and remove with synchronous and asynchronous with selector/callback and block implementations. What is the correct practice? Running the completion blocks on the main thread or a background thread?
For simple cases, I just parameterize it and do all the work i can on secondary threads:
By default, callbacks will be made on any thread (where it is most efficient and direct - typically once the operation has completed). This is the default because messaging via main can be quite costly.
The client may optionally specify that the message must be made on the main thread. This way, it requires one line or argument. If safety is more important than efficiency, then you may want to invert the default value.
You could also attempt to batch and coalesce some messages, or simply use a timer on the main run loop to vend.
Consider both joined and detached models for some of your work.
If you can reduce the task to a result (remove the capability for incremental updates, if not needed), then you can simply run the task, do the work, and provide the result (or error) when complete.
Apple's NSURLConnection class calls back to its delegate methods on the thread from which it was initiated, while doing its work on a background thread. That seems like a sensible procedure. It's likely that a user of your framework will not enjoy having to worry about thread safety when writing a simple callback block, as they would if you created a new thread to run it on.
The two sides of the coin: If the callback touches the GUI, it has to be run on the main thread. On the other hand, if it doesn't, and is going to do a lot of work, running it on the main thread will block the GUI, causing frustration for the end user.
It's probably best to put the callback on a known, documented thread, and let the app programmer make the determination of the effect on the GUI.

Objective C: How to kill a thread while in another thread in Objective-C?

I was trying to set up a multi thread app. One of the threads is working as background to get some data transfer. Right now this thread automatically kill itself after it's job done.
Somehow I need to kill this thread in another thread in order stop its job immediately. Are there any api or method for making this happen?
In short, you can't. Or, more precisely, you should not. Not ever and not under any circumstances.
There is absolutely no way for thread A to know the exact state of thread B when A kills B. If B is holding any locks or in the middle of a system call or calling into a system framework when A kills it, then the resulting state of your application is going to be nondeterministic.
Actually -- it will be somewhat deterministic in that you are pretty much guaranteed that a crash will happen sometime in the near future.
If you need to terminate thread B, you need to do so in a controlled fashion. The most common way is to have a cancel flag or method that can be set/called. thread B then needs to periodically check this flag or check to see if the method has been called, clean up whatever it is doing, and then exit.
That is, you are going to have to modify the logic in thread B to support this.
bbum is correct, you don't want to simply kill a thread. You can more safely kill a process, because it is isolated from the rest of the system. Because a thread shares memory and resources with the rest of the process, killing it would likely lead to all sorts of problems.
So, what are you supposed to do?
The only correct way of handling this is to have a way for your main thread to send a message to the worker thread telling it to quit. The worker thread must check for this message periodically and voluntarily quit.
An easy way to do this is with a flag, a boolean variable accessible by both threads. If you have multiple worker threads, you might need something more sophisticated, though.
Isn't that a bad idea? (If the other thread is in the middle of doing something in a critical section, it could leave stuff in an inconsistent state.) Couldn't you just set some shared flag variable, and have the other thread check it periodically to see if it should stop?
One thing you could do would be pass messages between the front thread and the background thread, potentially using something like this to facilitate message passing.
If you are using pthread then you try with 'pthread_kill' , I had tried long back it did not worked for me, basically if the thread is in some blocking call it won't work.
It is true that killing a thread is not good option, if you are looking for some kind for fix for some issue then you can try with this.
In my personal view it is best to let a thread run its course naturally. It's difficult to make guarantees about the effect of trying to kill a thread.