Use of CreateEvent() in Quake - c

I'm curious about the use of the CreateEvent() function in Quake.
We have the following global in the c file that WinMain() is defined in:
static HANDLE tevent;
In the WinMain() function itself, we see this:
tevent = CreateEvent(NULL, FALSE, FALSE, NULL);
The game exits if this creation fails.
It then appears in a following function:
void SleepUntilInput (int time)
{
MsgWaitForMultipleObjects (1, &tevent, FALSE, time, QS_ALLINPUT);
}
And finally CloseHandle(tevent) is called in the Quit function.
I'm unfamiliar with WinAPI, so this leaves me with two questions.
-What does this use of CreateEvent() return?
-How does this make the SleepUntilInput() function work properly?

CreateEvent returns the handle to a newly-created event.
SleepUntilInput uses the `MsgWaitForMultipleObjcts function to wait until one of three things happens:
The event is signaled, or
Input is available, or
time milliseconds have elapsed.
Since the code never signals the event, condition (1) never occurs, so the only things that will wake it up are (2) or (3).
Note that the event is not actually necessary. The code could have done
void SleepUntilInput (int time)
{
MsgWaitForMultipleObjects (0, NULL, FALSE, time, QS_ALLINPUT);
}
But whoever wrote the code didn't think of that, so they instead passed a dummy event.

Related

Is checking the Thread is "UI Thread" before Calling Dispatcher.Invoke redundant?

In regards to
Application.Current.Dispatcher.Invoke(action);
I have looked at CheckAccess() and various ways of determining whether i'm on the main UI thread. Though after looking at the Dispatcher Source code for Invoke, it seems to call CheckAccess() and performs other checks anyway
Invoke Source Code
public void Invoke(Action callback, DispatcherPriority priority, CancellationToken cancellationToken, TimeSpan timeout)
{
...
...
// Fast-Path: if on the same thread, and invoking at Send priority,
// and the cancellation token is not already canceled, then just
// call the callback directly.
if (!cancellationToken.IsCancellationRequested && priority == DispatcherPriority.Send && CheckAccess())
{
SynchronizationContext oldSynchronizationContext = SynchronizationContext.Current;
try
{
DispatcherSynchronizationContext newSynchronizationContext;
if (BaseCompatibilityPreferences.GetReuseDispatcherSynchronizationContextInstance())
{
newSynchronizationContext = _defaultDispatcherSynchronizationContext;
}
else
{
if (BaseCompatibilityPreferences.GetFlowDispatcherSynchronizationContextPriority())
{
newSynchronizationContext = new DispatcherSynchronizationContext(this, priority);
}
else
{
newSynchronizationContext = new DispatcherSynchronizationContext(this, DispatcherPriority.Normal);
}
}
SynchronizationContext.SetSynchronizationContext(newSynchronizationContext);
callback();
...
So the most reliable way to check whether my dialog needs to be invoked is by calling Invoke? looking at CheckAccess and SynchronisationContexts solutions when i dont have access to a Control seem to be redundant.
Is this the case or is there some edge cases i'm missing, or hidden performance hit i cant see?
I guess it depends.
If you're mainly after correctness and/or code brevity, then yes, the call is redundant - calling
Dispatcher.Invoke(action);
will be functionally equivalent1 to
if(Dispatcher.CheckAccess())
action();
else
Dispatcher.Invoke(action);
If however your concern is performance, then it's not so obvious. CheckAccess literally reads
return Thread == Thread.CurrentThread;
so even if it's called twice as many times, it will hardly be noticeable. Dispatcher.Invoke however does some additional work, such as argument checking and, possibly, swapping synchronization context, so I guess it potentially has larger overhead than a redundant call to CheckAccess(). But, as usual with performance optimization, there's no single right answer - it depends on your particular case (for example on the likelihood of this code being called from non-UI thread).
1 Obviously there may be additional things happening with the synchronization context when calling Dispatcher.Invoke, but unless action is making use of it, the result will be the same

Low Level DBus C API main loop

When trying to use a callback function for a DBus reply I get stuck on creating a good/well working main loop.
What I want to do is simple, make a DBus call and specify a function which should be called when the reply comes. This is because I do not want to block my thread for the whole time until a reply has been calculated and arrived.
I first use dbus_connection_send_with_reply(..) to get a DBusPendingCall, then i specify a callback function using dbus_pending_call_set_notify(..). Before doing this, when connecting to the bus, I have started another thread which should wait for a response and call the callback functions. I have found no examples at all and no very good documentation of how I should design a dbus main-loop like this. I have tried:
// Main dbus loop handling data transfer and callbacks..
void *dbus_main(void *args)
{
my_dbus dbus = (my_dbus)args;
while (MY_DBUS_STATUS_STOPPING != dbus->status
&& dbus_connection_read_write_dispatch(dbus->conn, -1))
;
return 0;
}
// Start the dbus main loop in a new thread
void dbus_main_start(my_dbus dbus) {
if (!pthread_create(&dbus->th, NULL, dbus_main, dbus)) {
// PRINT ERROR
}
}
My problem is two things:
I try to stop the app by setting the dbus->status flag to MY_DBUS_STATUS_STOPPING and waiting for the threads to join. This does not work if the thread is blocked in the dbus_connection_read_write_dispatch(..) function. If i want the app to stop fast then I need to specify a very short timeout. Can't I wake the blocked thread in some other way?
More seriously, with this code i don't get any callback from the method I call. If I add some fprintf(..) to write to stdout I might suddenly get my callback. It seems quite random, so maybe some kind of deadlock? I have tried having a dbus_connection_flush(..) between sending the message and adding the callback with _set_notify(..) function. Doesn't do any difference... But printing some letters to stdout in the same place fixes the problem. Printing to stdout in the dbus-main-loop insted of an empty ";" seems to do the trick sometimes...
So anyone who has an example of using the low-level dbus api together with async methods, ie not using _block(..)??
You can create a simple DBus application as follows...
To setup a server to handle incoming messages, call dbus_connection_register_object_path passing in a VTable containing function pointers to handle the messages. Such as:
{ .unregister_function = UnregisteredMessage, .message_function = ServiceMessage }
To send a new message, call dbus_connection_send_with_reply and then dbus_pending_call_set_notify to associate a callback function to handle the reply.
Next you will need to service DBus. This can be done in a separate thread or by calling periodically with non-blocking calls in the same thread, as shown below:
/* Non-blocking read of the next available message */
dbus_connection_read_write ( MyDBusConnection, 0 ) ;
while ( dbus_connection_get_dispatch_status ( MyDBusConnection ) == DBUS_DISPATCH_DATA_REMAINS )
{
dbus_connection_dispatch ( MyDBusConnection ) ;
}
There are some good example of using the DBUS C API here: http://www.matthew.ath.cx/misc/dbus
It is highly recommended that you use a D-Bus library other than libdbus, as libdbus is fiddly to use correctly, as you are finding. If possible, use GDBus or QtDBus instead, as they are much higher-level bindings which are easier to use. If you need a lower-level binding, sd-bus is more modern than libdbus.
If you use GDBus, you can use GMainLoop to implement a main loop. If you use sd-bus, you can use sd-event.

Timer to implement a time-out function

I'm writing a Windows (Win32) program in C, which features a worker thread to process data from a USB hardware device. The thread handling all works well, however I now need to add a timer to handle a timeout function. I don't need a callback function, just the ability to start a single shot timer, and to be able to test weather it's complete without sleeping, something like this:
start_timout(1000); // 1 second
while (timer_is_running())
{
doing stuff while waiting...
.
.
.
}
do stuff after timer is finished...
.
.
.
This would be running inside the worker thread.
I've looked at SetTimer(), and have tried creating a callback function that simply sets a global flag, then test for the flag, but that never gets set. I'm not sure if this is because I don't have a message handler inside my thread.
Any suggestions welcome.. Cheers!
Thanks for your reply, I had something working quite quickly. Here's a distillation of my working code:
#include <windows.h>
static void func(void)
{
HANDLE hTimer = NULL;
LARGE_INTEGER liDueTime;
liDueTime.QuadPart = -5000000LL; // 0.5 seconds
//liDueTime.QuadPart = -20000000LL; // 2 seconds
//liDueTime.QuadPart = -100000000LL; // 10 seconds
hTimer = CreateWaitableTimer(NULL, TRUE, NULL);
SetWaitableTimer(hTimer, &liDueTime, 0, NULL, NULL, 0);
while (WaitForSingleObject(hTimer, 0) == WAIT_TIMEOUT)
{
do stuff
}
}
Regards,
Toonie.
SetTimer requires you to catch the WM_TIMER event in a window and on top of that, is not very accurate. I wouldn't advise to use it.
Instead you could simply create another thread, let it do nothing but Sleep() for the specified time period (you could pass the time as parameter upon thread creation). You can then WaitForSingleObject(sleeper_thread, 0) to check if the timeout has elapsed.

Working with WINAPI with couple of threads

I've been working on WinAPI for a while, and I noticed that whenever I try to use WINAPI functions (such as create buttons/windows / update listview and such) inside a thread which isn't the main thread, it just wont show up.
So for example, if I want to add items to a ListView, and I call a function that takes a string and adds it to the listview, if I call the function from the main thread, it'll work great, but if I call it from a different thread, it won't work at all.
What can I do?
As with most (all?) GUI systems you need to update the GUI from the thread that owns the window (usually the main thread). You need to find a way to communicate between the two threads. In Win32 my preferred way is to send a user message to the GUI thread (via PostMessage) and update accordingly. You will need to ensure there's no concurrent access to data you send between them, for example protect global data with a Critical Section or something.
A simple example, semi pseudo code:
#define WM_MY_MESSAGE WM_USER+1
thread
{
do some number crunching...
// inform user
EnterCriticalSection(&MessageCrit);
strncpy(StatusMessageText, "Crunching away...", ARRAYSIZE(StatusMessageText));
LeaveCriticalSection(&MessageCrit);
PostMessage(hwndMain, WM_MY_MESSAGE, 0, 0); // You can utilize the params to your hearts content: structures, enums, etc...
}
guithread
{
switch (message)
{
case WM_INITDIALOG: // etc - whatever is in your normal message handler
break;
case WM_MY_MESSAGE:
ListView_InsertItem(...); // etc
EnterCriticalSection(&MessageCrit); // Protect the global data
ListView_SetItemText(item, StatusMessageText);
LeaveCriticalSection(&MessageCrit);
break;
}
}
You should either use PostMessage:
static LVITEM lvi = { ... };
PostMessage( myListView, LVM_INSERTITEM, 0, (LPARAM)&lvi );
or, if you need the return value, create a message pump for your thread first:
MSG msg;
PeekMessage( &msg, 0, 0, 0, PM_NOREMOVE );
static LVITEM lvi = { ... };
ListView_InsertItem( myListView, &lvi );
If you use PostMessage, be sure to keep the memory alive also after PostMessage returns, as the message is processed asynchronously by your main thread.

Calling thread cannot access object because different thread owns it

I thought I knew what causes this exception until I wrote this:
var menu = ViewConfigHelper.CreateObjectFromResource<Menu>(config, baseURI);
if (!menu.Dispatcher.CheckAccess())
{
throw new ArgumentException("Somethign wrong");
}
if (!LayoutRoot.Dispatcher.CheckAccess())
{
throw new ArgumentException("SOmethign wrong");
}
// exception throw here
LayoutRoot.Children.Insert(0, menu);
First line creates a Menu control from an embedded XAML file. Both CheckAccess calls return true. However, when last line is executed, an exception is thrown with the message "Caling thread cannot access object because differrent thread owns it." The code above is being executed within a method called immediately after InitializeComponent() that created LayoutRoot, on the same thread, I believe.
Someone please enlighten me. I am trying to create a multiple UI thread WPF app.
You are using CheckAccess() in reverse. You want to lose the ! signs before each check. See the example bit of code on the CheckAccess() MSDN page.
In the Winforms world you'd do a InvokeRequired() which is now the same thing as a !CheckAccess(). In your case because both values are returning true, and you are inverting them, neither if block is hit.
To expand a bit... in the Winforms world, the normal patter was:
if(InvokeRequired)
{
Invoke(...);
}
else
{
//do work
}
(or sometimes a return after invoke, if it was invoking the same method).
In WPF, CheckAccess() is similar to, but not identical to InvokeRequired... there for a pattern more along the lines of:
if (someUiControl.Dispatcher.CheckAccess())
{
//Doing an update from this thread is safe, so we can do so here.
}
else
{
// This thread does not have access to the UI thread.
// Call the update thread via a Dispatcher.BeginInvoke() call.
}
The key difference between is that InvokeRequired() returning true meant it was UNSAFE to do the update in the current thread... while a true from CheckAccess() means it is SAFE.

Resources