Can I have multiple GMainContext per GMainLoop? - glib

How will a GMainLoop look when I add two GMainContext. The documentation is not that clear. But Can someone verify that adding GMainContext does not create a thread. It just adds another event loop for another set of Gsources.
Which GMainContext will be prioritized, when there are 2 contexts attached to the GMainLoop. I assume its thread-default context but just want to make sure.
If someone can also throw an example of why someone might need two GMainContext's instead of just adding the Gsource to the first context.
Basically I am just getting started with GMain stuff and I have an GMainLoop with GmainContext all setup. But wanted to add some idle task on another thread, but I got confused if I should create a new thread or just create a new GMainContext.

How will a GMainLoop look when I add two GMainContext.
You can only have one GMainContext per GMainLoop. A GMainLoop is at its core just:
while (!main_loop_quit_called)
g_main_context_iteration (loop->context, TRUE);
But Can someone verify that adding GMainContext does not create a thread. It just adds another event loop for another set of Gsources.
Correct. You have to create threads manually.
Which GMainContext will be prioritized, when there are 2 contexts attached to the GMainLoop. I assume its thread-default context but just want to make sure.
You can’t have two GMainContexts attached to one GMainLoop, because you can’t iterate one GMainContext while blocking on another. Each GMainContext boils down to a poll() call, and you can’t have two of those running in the same thread concurrently.
The concept of a ‘thread-default context’ just exists so that operations don’t all have to take a GMainContext * as an argument.
If someone can also throw an example of why someone might need two GMainContext's instead of just adding the Gsource to the first context.
This question is very vague and open-ended. Please explain what it is you’re trying to achieve.
Basically I am just getting started with GMain stuff and I have an GMainLoop with GmainContext all setup. But wanted to add some idle task on another thread, but I got confused if I should create a new thread or just create a new GMainContext.
If you really need a second thread (typically, you don’t), it should have exactly one GMainContext.
See the guidelines on main contexts.

Related

How to make a function atomic in Swift?

I'm currently writing an iOS app in Swift, and I encountered the following problem: I have an object A. The problem is that while there is only one thread for the app (I didn't create separate threads), object A gets modified when
1) a certain NSTimer() triggers
2) a certain observeValueForKeyPath() triggers
3) a certain callback from Parse triggers.
From what I know, all the above three cases work kind of like a software interrupt. So as the code run, if NSTimer()/observeValueForKeyPath()/callback from Parse happens, current code gets interrupted and jumps to corresponding code. This is not a race condition (since just one thread), and I don't think something like this https://gist.github.com/Kaelten/7914a8128eca45f081b3 can solve this problem.
There is a specific function B called in all three cases to modify object A, so I'm thinking if I can make this function B atomic, then this problem is solved. Is there a way to do this?
You are making some incorrect assumptions. None of the things you mention interrupt the processor. 1 and 2 both operate synchronously. The timer won't fire or observeValueForKeyPath won't be called until your code finishes and your app services the event loop.
Atomic properties or other synchronization techniques are only meaningful for concurrent (multi-threaded) code. If memory serves, Atomic is only for properties, not other methods/functions.
I believe Parse uses completion blocks that are run on a background thread, in which case your #3 **is* using separate threads, even though you didn't realize that you were doing so. This is the only case in which you need to be worried about synchronization. In that case the simplest thing is to simply bracket your completion block code inside a call to dispatch_async(dispatch_get_main_queue()), which makes all the code in the dispatch_async closure run on the main, avoiding concurrency issues entirely.

How to log/ find every single method call on the main thread automatically?

Is there a way to follow a chain every function call on the main thread without having to manually write a log statement in every method?
For example, I would love to see (automatically)
- SomeViewController:viewDidAppear(...)
- SomeModel:loadModel(...)
- SomeService:findModel(...)
You might look at this and say "oh shoot, I shouldn't be finding the model on the main thread."
Of course this presumes it's filtering out all the
framework calls and only displaying the user's library of code. It's basically a means for me to find out where it's not smart for me to be calling things on the main thread.
Possible?

Requesting Scalar Values from main thread managedobjectcontext from background thread

I have a method that runs in a background thread using a copy of NSManagedObjectContext which is specially generated when the background thread starts as per Apples recommendations.
In this method it makes a call to shared instance of a class, this shared instance is used for managing property values.
The shared instance that managed properties uses a NSManagedObjectContext on the main thread, now even though the background thread method should not use the NSManagedObjectContext on the main thread, it shouldn't really matter if the shared property manager class does or does not use the such a context as it only returns scalar values back to the background thread (at least that's my understanding).
So, why does the shared property class hang when retrieving values via the main threads context when called from the background thread? It doesn't need to pass an NSManagedObject or even update one so I cannot see what difference it would make.
I can appreciate that my approach is probably wrong but I want to understand at a base level why this is. At the moment I cannot understand this whole system enough to be able to think beyond Apples recommended methods of implementation and that's just a black magic approach which I don't like.
Any help is greatly appreciated.
Does using:
[theContext performBlock:^{
// do stuff on the context's queue, launch asynchronously
}];
-- or --
[theContext performBlockAndWait:^{
// do stuff on the context's queue, run synchronously
}];
-- just work for you? If so, you're done.
If not, take a long, hard look at how your contexts are setup, being passed around, and used. If they all share a root context, you should be able to "move" data between them easily, so long as you lookup any objectIDs always on your current context.
Contexts are bound to threads/queues, basically, so always use a given context as a a reference for where to do work. performBlock: is one way to do this.

slow memory release (refcounted structure) - Is my workaround a good way?

in my program i can load a Catalog: ICatalog
a Catalog here contains a lot of refcounted structures (Icollections of IItems, IElements, IRules, etc.)
when I want to change to another catalog,
I load a new Catalog
but the automatic release of the previous ICatalog instance takes time, freezing my application for 2 second or more.
my question is :
I want to defer the release of the old (and no more used) ICatalog instance to another thread.
I've not tested it already, but I intend to create a new thread with :
ErazerThread.OldCatalog := Catalog; // old catalog refcount jumps to 2
Catalog := LoadNewCatalog(...); // old catalog refcount =1
ErazerThread.Execute; //just set OldCatalog to nil.
this way, I expect the release to occur in the thread, and my application not
beeing freezed anymore.
Is it safe (and good practice) ?
Do you have examples of existing code already perfoming release with a similar method ?
I would let such thread block on some threadsafe queue(*), and push the interfaces to release into that queue as iunknowns.
Note however that if the releasing touches a lock that your memory manager uses (like a global heapmanager lock), then this is futile, since your mainthread will block on the first heapmanager access.
With a heapmanager with per thread pools, allocating many items in one thread and releasing it in a different thread might frustrate coalescing and reuse of (small) blocks algorithms.
I still think the way you describe is generally sound when implemented properly. But
this is from a theoretic perspective to show that there might be a link from the 2nd thread to the mainthread via the heapmanager.
(*) Simplest way is to add it to a tthreadlist and use tevent to signal that an element was added.
That looks OK, but don't call the thread's Execute method directly; that will run the thread object's code in the current thread instead of the one that the thread object creates. Call Start or Resume instead.

Does pthread_detach free up the stack allocated to the child thread, after the child thread as exited

I have used pthread_detach inorder to free up the stack allocated to the child thread, but this is not working, I guess it does not free up the memory.....
I don't want to use pthread_join. I know join assures me of freeing up the stack for child, but, I don't want the parent to hang up until the child thread terminates, I want my parent to do some other work in the mean time. So, I have used detach, as it will not block the parent thread.
Please, help me. I have been stuck..
this is not working
Yes it is. You are likely mis-interpreting your observations.
I want my parent to do some other work in the mean time
That's usually the reason to create threads in the first place, and you can do that:
pthread_create(...);
do_some_work(); // both current and new threads work in parallel
pthread_join(...); // wait for both threads to finish
report_results();
I don't want to use pthread_join. I know join assures me of freeing up the stack for child
Above statement is false: it assures no such thing. A common implementation will cache the now available child stack for reuse (in case you'll create another thread shortly).
YES - according to http://cursuri.cs.pub.ro/~apc/2003/resources/pthreads/uguide/users-16.htm it frees memory either when the thread ends or immediately if the thread has already ended...
As you don't provide any clue as how you determine that the memory is not freed up I can only assume that the method you use to determine it is not sufficient...

Resources