I have one problem. I'm creating interface generation library, called libgreattao. It is able to using many backends to rendering GUI, while running in GUI mode. The problem is in GTK+2.0 backend. I must run main loop and on some event exits from it to destroy window in next step. On window's destroy event I will exit from main loop again - and do only this. Why I call main loop again? Because I must handle events created, while destroying window(window must destroy all it's control and hide). The problem is: callback for destroy signal is called once gtk_widget_destroy is called. I must ensure callback pass by application are called in main loop to allow exit from it, so I define custom signal for class GTKWIDGET. Of course, I can use workarounds, like destroying window in first signal type(the signal which ends main loop), but my library should works in any cases.
I have found solution, but not very good. I must add timeout event, which will emit my signal. I didn't find better solution yet.
Related
Tell me please, here is a quote from reference section 3 ("Running an event loop") of Nick Mathewson's book on Libevent:
By default, the event_base_loop() function runs an event_base until
there are no more events registered in it.
Honestly, I just can't understand this phrase.
What means - "until there are no more events registered".
How does a loop know that there are no more new events ?? There can be a time interval between events - 1 second, 1 hour ...
How does Libevent know that events are over?
PS: I'm trying to compare the work of the event_base_loop () function with the GetQueuedCompletionStatus () function on windows and I don't get it. Because GetQueuedCompletionStatus works in an infinite loop - whether there are events or not - GetQueuedCompletionStatus waits for an infinitely new event and does not complete if there are none.
PS1:I was in a hurry and did not finish the chapter on "Working with an event loop".
It says that you can redefine the behavior of the event_base_loop () function by passing it a flag in the second parameter - EVLOOP_NO_EXIT_ON_EMPTY.
This will mean that the function will wait for new events indefinitely or until I want to exit the event_base_loop () loop manually via event_base_loopbreak / event_base_loopexit.
Note it says "no more events registered", rather than "no more events". By default, the event loop will exit when the event base runs empty, even though more events could happen later. This is restated in a different way both later in the chapter:
Ordinarily, the loop will exit as soon as it has no pending or active events.
and in the API documentation for event_base_loop():
By default, this loop will run the event base until either there are no more pending or active events, or until something calls event_base_loopbreak() or event_base_loopexit().
As noted in the question, EVLOOP_NO_EXIT_ON_EMPTY can change this behavior to work more like a typical event queue, waiting for events (unless EVLOOP_NONBLOCK was set) and dispatching them when they arrive.
"Running an event loop" contains pseudocode for event_base_loop() that should also help clarify the behavior.
In comparison, GetQueuedCompletionStatus will wait for and operate on a single packet (note: the wait is not likely a busyloop but based on some other multitasking technologies, such as interrupts and thread synchronization primitives; the exact method is an implementation detail, and shouldn't affect use). It's most similar to event_base_loop() with the flags EVLOOP_ONCE | EVLOOP_NO_EXIT_ON_EMPTY, though event_base_loop may process multiple events of the same priority if they happen to come in before the first event is fully handled. Coming from the other direction, if 0 is passed for the dwMilliseconds argument to GetQueuedCompletionStatus, it behaves like event_base_loop()'s default behavior, exiting immediately if there are no packets in the I/O completion queue.
I want to render a chart with the DevExpress ChartControl via the WiForm DrawToBitmap() function on a separate thread.
I try something like:
Form yourForm;
Thread thread = new Thread( () =>
{
yourForm = new HiddenForm();
Application.Run(yourForm);
});
thread.ApartmentState = ApartmentState.STA;
thread.Start();
yourForm.Invoke(chartRenderingFunction)
And simple make sure the Hidden never actually gets displayed. However, I don't need that hidden form, and there is a parameterless form of Application.Run(). However, if I run that, it doesn't return. So my question is once I call Application.Run() inside a thread, how do I inject code in it?
Well, you actually really do need that hidden window. The only way to get code to run on that thread. Somebody must call PostMessage() and that requires a window handle. Your Invoke() call makes that call. You really should use BeginInvoke() instead, there's no point in starting a thread if you are going to wait for the call to complete.
Using Application.Run(yourForm) is going to make the window visible. You can stop it from becoming visible by overriding the SetVisibleCore() method in your HiddenForm class:
protected override void SetVisibleCore(bool value) {
if (!this.IsHandleCreated) {
CreateHandle();
value = false;
ThreadReady.Set();
}
base.SetVisibleCore(value);
}
The CreateHandle() call is necessary to make sure that the window is created so it can process the PostMessage() notifications. Also note the added AutoResetEvent (ThreadReady), you are going to have to call ThreadReady.WaitOne() after calling the thread's Start() method to ensure that your BeginInvoke() call is going to work. Dispose the form to get the thread to exit or call Application.Exit().
Last but not least, be very careful with using non-trivial controls on that thread. A chart control certainly is not indicated. You'll have long-lasting problems if that control uses the SystemEvents class for example. Your worker thread will get it to raise events on that worker thread. But it won't be around anymore after the chart is printed. You'll now get the events fired on an arbitrary threadpool thread, very nasty. A deadlock is a common mishap, particularly apt to trigger when locking the workstation.
When running an event loop in libuv using the uv_run function, there's a "mode" parameter that is used with the following values:
UV_RUN_DEFAULT
UV_RUN_ONCE
UV_RUN_NOWAIT
The first two are obvious. UV_RUN_DEFAULT runs the event loop until there are no more events, and UV_RUN_ONCE processing a single event from the loop. However, UV_RUN_NOWAIT doesn't seem to be a separate mode, but rather a flag that can be ORed with one of the other two values.
By default, this function blocks until events are done processing, and UV_RUN_NOWAIT makes it nonblocking, but any documentation I can find on it ends there. My question is, if you run the event loop nonblocking, how are callbacks handled?
The libuv event model is single-threaded (reactor pattern), so I'd assume it needs to block to be able to call the callbacks, but if the main thread is occupied, what happens to an event after it's processed? Will the callback be "queued" until libuv gets control of the main thread again? Or will the callbacks be dispatched on another thread?
Callbacks are handled in the same manner. They will run within the thread that is in uv_run().
Per the documentation:
UV_RUN_DEFAULT: Runs the event loop until the reference count drops to zero. Always returns zero.
UV_RUN_ONCE: Poll for new events once. Note that this function blocks if there are no pending events. Returns zero when done (no active handles or requests left), or non-zero if more events are expected (meaning you should run the event loop again sometime in the future).
UV_RUN_NOWAIT: Poll for new events once but don't block if there are no pending events.
Consider the case where a program has a single watcher listening to a socket. In this scenario, an event would be created when the socket has received data.
UV_RUN_DEFAULT will block the caller even if the socket does not have data. The caller will return from uv_run(), when either:
The loop has been explicitly stopped, via uv_stop()
No more watchers are running in the loop. For example, the only watcher has been stopped.
UV_RUN_ONCE will block the caller even if the socket does not have data. The caller will return from uv_run(), when any of the following occur:
The loop has been explicitly stopped, via uv_stop()
No more watchers are running in the loop. For example, the only watcher has been stopped.
It has handled a max of one event. For example, the socket received data, and the user callback has been invoked. Additional events may be ready to be handled, but will not be handled in the current uv_run() call.
UV_RUN_NOWAIT will return if the socket does not have data.
Often times, running an event-loop in a non-blocking manner is done to integrate with other event-loops. Consider an application that has two event loops: libuv for backend work and Qt UI (which is driven by its own event loop). Being able to run the event loop in a non-blocking manner allows for a single thread to dispatch events on both event-loops. Here is a simplistic overview showing two libuv loops being handled by a single thread:
uv_loop_t *loop1 = uv_loop_new();
uv_loop_t *loop2 = uv_loop_new();
// create, initialize, and start a watcher for each loop.
...
// Handle two event loops with a single thread.
while (uv_run(loop1, UV_RUN_NOWAIT) || uv_run(loop2, UV_RUN_NOWAIT));
Without using UV_RUN_NOWAIT, loop2 would only run once loop1 or loop1's watchers have been stopped.
For more information, consider reading the Advanced Event Loops and Processes sections of An Introduction to libuv.
I checked which thread my Dispose(bool) methods get called on. When the app is running, it is always the UI thread that calls Dispose, say when clicking on the [x] to close a Form. But when I close the whole app, many Dispose methods get called on a (single) different thread. When I dump the stack trace, I see that they all get called from
System.ComponentModel.Component.Finalize().
Does that mean all my Dispose methods need to be made thread-safe? Or is WinForms guaranteeing that the UI thread won't touch these objects any more and does it also establish some kind of "happened-before" relationship between the UI thread and the one that's now finalizing?
Yes, the finalizer works on a separate thread. Usually this is no problem, because when an Object is finalized it is not reachable by any user thread (like the UI thread) anymore. So, you usually do not have to be thread-safe within your finalizer.
I have a problem here and need your help. I've been trying to capture keyboard strokes from a created window using cvWaitKey() function. The function works fine if I called the cvWaitKey from the same thread that created the window, but when I create the window from a thread and call cvWaitKey() from another thread it doesn't return correct key, it blocks for cvWaitKey(0) and returns -1 for any timeout grater than zero.
Yes, this cannot work. cvWaitKey() is implemented by calling the PeekMessage() API function. That can only see messages on the message queue which is associated with the thread. The thread you created doesn't have any windows.
There is no obvious workaround for this, you have to call it on the thread that created the window. Calling GetAsyncKeyState() could work, a very different approach though.
In you "other" thread, you can set some shared variable to true or false (or some value), and make the "window thread" checks it before deciding whether to call cvWaitKey() in its local scope.