I have 3rd party library, which is nonblocking and has its own event loop, it accepts pointer of callback function and executes it in same thread. What I want is to post event from this thread to nginx main thread, something like ngx_add_timer but without time option, to safely add event to nginx main event loop.
So very late to the party here, but I found this thread in my research and wanted to post the solution I came up with
Nginx has a mechanism to post from a worker thread - one that is perhaps running another event loop - to the main thread of the nginx worker process. That is 'ngx_post_event' which lets you post an event handler which will be invoked at some point in the future by the main thread.
You have to choose an event queue to post it on, but whatever you're doing, the answer is certainly &ngx_posted_events.
Here we come to the problem (and a solution): if you do this, your event handler will not get invoked in a timely manner because the main nginx worker process thread is waiting on i/o. It won't even deign to look at the posted events queue until it has some 'real' work to do from i/o.
The solution that's working for me currently (and bear in mind this is only on Linux), is to send the main thread a signal which will wake it up from its epoll_wait reverie so it can get to work on the pipeline coming from the other thread.
So here's what worked:
First grab the id of the worker process main thread and hold it in some process-global state:
// In you 'c' source:
static pthread_t nginx_thread;
// In some code that runs once at nginx startup (in my case the module's preconfiguration step)
nginx_thread = pthread_self();
Now when to post your callback you use the ngx_post_event call I mentioned earlier, then send a SIGIO signal to the main thread to wake up the epoll_wait operation
// Post the event and wake up the Nginx epoll event loop
ngx_post_event( event_ptr, &ngx_posted_events );
pthread_kill( nginx_thread, SIGIO );
The SIGIO event is handled in the main Nginx signal handler - and is ignored (well that's what the log says), but crucially, causes the posted events to be processed immediately.
That's it - and it seems to be working so far... please do point out anything stupid I've done.
To complete the story, you'll need the following #includes:
#include <pthread.h>
#include <signal.h>
Related
I want to have the code executed by the OnTimer event to be executed in a separate (non-Main) background thread. this code does not access or communicate with the main thread/GUI. Simple question, I get the timer (TJvThreadTimer) is executed in it's own background thread, but:
Does the code contained in TJvThreadTimer.OnTimer event get executed in that background thread as well?
It is unclear from the limited documentation.
Thanks......
If you look at the timer's source code for yourself, you will see that the OnTimer event handler is called inside of a class method that is Synchronize()'ed by the internal background thread, which means the event handler runs in the main UI thread.
As I understand , a Node JS server continues to listen on a port for any incoming requests which means the thread is continuously busy ? When does it break from this continuous never ending loop and check if there are any events to be processed from the call back queue?
2) When Node JS starts executing code of callback functions, the server is essentially stopped? It is not listening for further requests? I mean since only single thread is going to do both the task only one can be done at a time?
Is this understanding correct or there's more to it?
Yes, you are right. Everything in nodejs runs on the main thread except the I/o calls and fs file calls which go into to OS kernel and thread pool respectively for execution. All the synchronous code runs on the main thread and while this code is running, nodejs cannot process any further requests. That is why it is not advisable to use a long for loop because it may block the main thread for much time. You need to make child threads to handle that.
Node thread keeps an event loop and whenever any task get completed, it fires the corresponding event which signals the event listener function to get executed. The event loop simply iterate over the event queue which is basically a list of events and callbacks of completed operations. there is generally a main loop that listens for events, and then triggers a callback function when one of those events is detected.
(source: abdelraoof.com)
Similar event loop questions are here:
Node.js Event loop
Understanding the Event Loop
Source:
http://abdelraoof.com/blog/2015/10/28/understanding-nodejs-event-loop/
http://www.tutorialspoint.com/nodejs/nodejs_event_loop.htm
http://chimera.labs.oreilly.com/books/1234000001808/ch03.html#chap3_id35941348
I have a thread with a TCP Socket that connects to a server and waits for data in a while loop, so the thread never ends. When the socket receives data, it is parsed, and based on the opcode of the packet, should call x function. Whats the fastest/best way to go about that?
I read around that doing some kind of task/message queue system is a way of doing it, but not sure if there is any better options.
Should mention that I can not use boost:
Edit: Sorry, half asleep haha.
Here is the loop from thread x:
while (Running)
{
if (client.IsConnected())
{
Recieve();
}
FPlatformProcess::Sleep(0.01);
}
In the Receive function, it parses the data, and based on the packet opcode, I need to be able to call a function on the main thread (the GUI thread), because a lot of the packets are to spawn GUI objects, and I can't create GUI objects from any other thread than the main one.
So basically: I have a main thread, that spawns a new thread that enters a loop, listens for data, and I need to be able to call a function from the 2nd thread that runs on the main thread.
I am using NSURLSession dataTaskWithURL:completionHandler. It looks like completionHandler is executed in a thread which is different than the thread(in my case, it's the main thread) which calls dataTaskWithURL. So my question is, since it is asynchronized, is it possible that the main thread exit, but the completionHandler thread is still running since the response has not come back, which is the case I am trying to avoid. If this could happen, how should I solve the problem? BTW, I am building this as a framework, not an application.Thanks.
In the first part of your question you seem un-sure that the completion handler is running on a different thread. To confirm this let's look at the NSURLSession Class Reference. If we look at the "Creating a Session" section we can see in the description for the following method the answer.
+ sessionWithConfiguration:delegate:delegateQueue:
Swift
init(configuration configuration: NSURLSessionConfiguration,
delegate delegate: NSURLSessionDelegate?,
delegateQueue queue: NSOperationQueue?)
Objective-C
+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration
delegate:(id<NSURLSessionDelegate>)delegate
delegateQueue:(NSOperationQueue *)queue
In the parameters table for the NSOperationQueue queue parameter is the following quote.
An operation queue for scheduling the delegate calls and completion handlers. The queue need not be a serial queue. If nil, the session creates a serial operation queue for performing all delegate method calls and completion handler calls.
So we can see the default behavior is to provide a queue whether from the developer or as the default class behavior. Again we can see this in the comments for the method + sessionWithConfiguration:
Discussion
Calling this method is equivalent to calling
sessionWithConfiguration:delegate:delegateQueue: with a nil delegate
and queue.
If you would like a more information you should read Apple's Concurrency Programming Guide. This is also useful in understanding Apple's approach to threading in general.
So the completion handler from - dataTaskWithURL:completionHandler: is running on a different queue, with queues normally providing their own thread(s). This leads the main component of your question. Can the main thread exit, while the completion handler is still running?
The concise answer is no, but why?
To answer this answer this we again turn to Apple's documentation, to a document that everyone should read early in their app developer career!
The App Programming Guide
The Main Run Loop
An app’s main run loop processes all user-related events. The
UIApplication object sets up the main run loop at launch time and uses
it to process events and handle updates to view-based interfaces. As
the name suggests, the main run loop executes on the app’s main
thread. This behavior ensures that user-related events are processed
serially in the order in which they were received.
All of the user interact happens on the main thread - no main thread, no main run loop, no app! So the possible condition you question mentions should never exist!
Apple seems more concerned with you doing background work on the main thread. Checkout the section "Move Work off the Main Thread"...
Be sure to limit the type of work you do on the main thread of your
app. The main thread is where your app handles touch events and other
user input. To ensure that your app is always responsive to the user,
you should never use the main thread to perform long-running or
potentially unbounded tasks, such as tasks that access the network.
Instead, you should always move those tasks onto background threads.
The preferred way to do so is to use Grand Central Dispatch (GCD) or
NSOperation objects to perform tasks asynchronously.
I know this answer is long winded, but I felt the need to offer insight and detail in answering your question - "the why" is just as important and it was good review :)
NSURLSessionTasks always run in background by default that's why we have completion handler which can be used when we get response from Web service.
If you don't get any response explore your request URL and whether HTTPHeaderFields are set properly.
Paste your code so that we can help it
I just asked the same question. Then figured out the answer. The thread of the completion handler is setup in the init of the NSURLSession.
From the documentation:
init(configuration configuration: NSURLSessionConfiguration,
delegate delegate: NSURLSessionDelegate?,
delegateQueue queue: NSOperationQueue?)`
queue - A queue for scheduling the delegate calls and completion handlers. If nil, the session creates a serial operation queue for performing all delegate method calls and completion handler calls.*
My code that sets up for completion on main thread:
var session = NSURLSession(configuration: configuration, delegate:nil, delegateQueue:NSOperationQueue.mainQueue())
(Shown in Swift, Objective-C the same) Maybe post more code if this does not solve.
At the moment, I am using WaitForSingleObject to wait for a sub-task thread to complete. Unfortunately, this causes my GUI to lock up. What I would like to do instead, is set a handler (in the GUI thread) that will be called after the sub-task thread is complete. Is there another function for this?
What you can do is to let the last thing that your thread does be posting a custom message to your window. Then handle that as a regular message using MFC's message map. If you cannot change the thread code, you can create a new thread that waits for your thread and then sends the message.
As you already noticed, it is not a good idea to lock up the GUI thread...
Edit: Posting the message is done using the PostMessage function as pointed out by Hans in the comments.
Could also have a look at MsgWaitForMultipleObjects (or MsgWaitForMultipleObjectsEx).
These allow a thread to wait for event handles and service windows messages (examine the return value to see what causes the call to return). Examples of usage should be available via a goodle search.
http://msdn.microsoft.com/en-us/library/ms684245(VS.85).aspx