I want to implement a scheduler class, which any object can use to schedule timeouts and cancel then if necessary. When a timeout expires, this information will be sent to the timeout setter/owner at that time asynchronously.
So, for this purpose, I have 2 fundamental classes WindowsTimeout and WindowsScheduler.
class WindowsTimeout
{
bool mCancelled;
int mTimerID; // Windows handle to identify the actual timer set.
ITimeoutReceiver* mSetter;
int cancel()
{
mCancelled = true;
if ( timeKillEvent(mTimerID) == SUCCESS) // Line under question # 1
{
delete this; // Timeout instance is self-destroyed.
return 0; // ok. OS Timer resource given back.
}
return 1; // fail. OS Timer resource not given back.
}
WindowsTimeout(ITimeoutReceiver* setter, int timerID)
{
mSetter = setter;
mTimerID = timerID;
}
};
class WindowsScheduler
{
static void CALLBACK timerFunction(UINT uID,UINT uMsg,DWORD dwUser,DWORD dw1,DWORD dw2)
{
WindowsTimeout* timeout = (WindowsTimeout*) uMsg;
if (timeout->mCancelled)
delete timeout;
else
timeout->mDestination->GEN(evTimeout(timeout));
}
WindowsTimeout* schedule(ITimeoutReceiver* setter, TimeUnit t)
{
int timerID = timeSetEvent(...);
if (timerID == SUCCESS)
{
return WindowsTimeout(setter, timerID);
}
return 0;
}
};
My questions are:
Q.1. When a WindowsScheduler::timerFunction() call is made, this call is performed in which context ? It is simply a callback function and I think, it is performed by the OS context, right ? If it is so, does this calling pre-empt any other tasks already running ? I mean do callbacks have higher priority than any other user-task ?
Q.2. When a timeout setter wants to cancel its timeout, it calls WindowsTimeout::cancel().
However, there is always a possibility that timerFunction static call to be callbacked by OS, pre-empting the cancel operation, for example, just after mCancelled = true statement. In such a case, the timeout instance will be deleted by the callback function.
When the pre-empted cancel() function comes again, after the callback function completes execution, will try to access an attribute of the deleted instance (mTimerID), as you can see on the line : "Line under question # 1" in the code.
How can I avoid such a case ?
Please note that, this question is an improved version of the previos one of my own here:
Windows multimedia timer with callback argument
Q1 - I believe it gets called within a thread allocated by the timer API. I'm not sure, but I wouldn't be surprised if the thread ran at a very high priority. (In Windows, that doesn't necessarily mean it will completely preempt other threads, it just means it will get more cycles than other threads).
Q2 - I started to sketch out a solution for this, but then realized it was a bit harder than I thought. Personally, I would maintain a hash table that maps timerIDs to your WindowsTimeout object instances. The hash table could be a simple std::map instance that's guarded by a critical section. When the timer callback occurs, it enters the critical section and tries to obtain the WindowsTimer instance pointer, and then flags the WindowsTimer instance as having been executed, exits the critical section, and then actually executes the callback. In the event that the hash table doesn't contain the WindowsTimer instance, it means the caller has already removed it. Be very careful here.
One subtle bug in your own code above:
WindowsTimeout* schedule(ITimeoutReceiver* setter, TimeUnit t)
{
int timerID = timeSetEvent(...);
if (timerID == SUCCESS)
{
return WindowsTimeout(setter, timerID);
}
return 0;
}
};
In your schedule method, it's entirely possible that the callback scheduled by timeSetEvent will return BEFORE you can create an instance of WindowsTimeout.
Related
AVFormatContext's interrupt_callback field is a
Custom interrupt callbacks for the I/O layer.
It's type is AVIOInterruptCB, and it explains in comment section:
Callback for checking whether to abort blocking functions.
AVERROR_EXIT is returned in this case by the interrupted function. During blocking operations, callback is called with opaque as parameter. If the callback returns 1, the blocking operation will be aborted.
No members can be added to this struct without a major bump, if new elements have been added after this struct in AVFormatContext or AVIOContext.
I have 2 questions:
what does the last section means? Especially "without a major bump"?
If I use this along with an RTSP source, when I close the input by avformat_close_input, the "TEARDOWN" message is being sent out, however it won't reach the RTSP server.
For 2: here is a quick pseudo-code for demo:
int pkts = 0;
bool early_exit = false;
int InterruptCallback(void* ctx) {
return early_exit ? 1 : 0;
}
void main() {
ctx = avformat_alloc_context
ctx->interrupt_callback.callback = InterruptCallback;
avformat_open_input
avformat_find_stream_info
pkts=0;
while(!early_exit) {
av_read_frame
if (pkts++ > 100) early_exit=true;
}
avformat_close_input
}
In case I don't use the interrupt callback at all, TEARDOWN is being sent out, and it also reaches the RTSP server so it can actually tear down the connection. Otherwise, it won't tear down it, and I have to wait until TCP socket times out.
What is the proper way of using this interrupt callback?
It means that they are not going to change anything for this structure (AVIOInterruptCB). However, if thats the case it would be in a major bump (major change from 4.4 eg to 5.0)
You need to pass a meaningful parameter to void* ctx. Anything that you like so you can check it within the static function. For example a bool that you will set as cancel so you will interrupt the av_read_frame (which will return an AVERROR_EXIT). Usually you pass a class of your decoder context or something similar which also holds all the info that you required to check whether to return 1 to interrupt or 0 to continue the requests properly. A real example would be that you open a wrong rtsp and then you want to open another one (the right one) so you need to cancel your previous requests.
I have a main thread that fires off several other threads to complete various items of work based on what the user choose from the main UI. Normally I'd use WaitForMultipleObjects() with bWaitAll set to TRUE. However, in this case those other threads will log output to another window that uses a mutex to ensure the threads only output one at a time. Part of that process uses SendMessage() to send get the text size and send the text to the windows which will hang if using WaitForMultipleObjects() since it's running from the main UI thread. So I moved over to use MsgWaitForMultipleObjects with QS_SENDMESSAGE flag, only it's problem is the logic for bWaitAll which states it will only return if all objects are signaled AND an input event occurred (instead of returning when all objects are signaled OR an input event occurred). Had the logic been OR this should have worked:
DWORD waitres=WAIT_FAILED;
while (1)
{
MSG msg;
while (::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
// mfc message pump
if (!theApp.PumpMessage()) {
// program end request
// TO DO
}
}
// MFC idel processing
LONG lidlecount = 0;
while (theApp.OnIdle(lidlecount++));
// our wait
waitres = ::MsgWaitForMultipleObjects(threadcount, threadhandles, TRUE, INFINITE, QS_SENDMESSAGE);
// check if ended due to message
if (waitres!=WAIT_OBJECT_0+threadcount) {
// no, exit loop
break;
}
}
Rather than fire off a thread that then fires off the other threads I wondered what is the correct way to handle this from the main thread? I thought about using bWaitAll FALSE then using WaitForMultipleObjects() with bWaitAll set to TRUE and the dwMilliseconds set to 0 (or 1) and checking the result to see if completed. If not, it would need to loop back to the top of the loop and then to MsgWaitForMultipleObjects() which when using bWaitAll FALSE could return right away if one of the many threads completed (say 1 thread of 10 completed, I could check as mentioned above if all completed, but when going back with bWaitAll FALSE it will just return and not wait).
So what is the proper way to handle waiting for multiple threads (that use SendMessage()) to complete in the main thread of an MFC application?
Thanks.
So what is the proper way to handle waiting for multiple threads to
complete
need create some structure, with reference count and pass pointer to this structure to every thread. here also probably exist sense have some common task data. and HWND of some window in main(GUI) thread. when worked thread exit - it release reference on object. when last thread exit - delete object and post some message to window, from main thread.
so we not need store thread handles (can just close it) and wait om multiple handles. instead we got some window message when all thread finish task
example of code
struct Task
{
HWND _hwnd;
LONG _dwRefCount = 1;
// some common task data probably ..
Task(HWND hwnd) : _hwnd(hwnd) {}
~Task() {
PostMessageW(_hwnd, WM_USER, 0, 0);// WM_USER as demo only
}
void AddRef(){
InterlockedIncrementNoFence(&_dwRefCount);
}
void Release(){
if (!InterlockedDecrement(&_dwRefCount)) delete this;
}
};
ULONG CALLBACK WorkThread(void* pTask)
{
WCHAR sz[16];
swprintf_s(sz, _countof(sz), L"%x", GetCurrentThreadId());
MessageBoxW(0, L"working...", sz, MB_ICONINFORMATION|MB_OK);
reinterpret_cast<Task*>(pTask)->Release();
return 0;
}
void StartTask(HWND hwnd, ULONG n)
{
if (Task* pTask = new Task(hwnd))
{
do
{
pTask->AddRef();
if (HANDLE hThread = CreateThread(0, 0, WorkThread, pTask, 0, 0))
{
CloseHandle(hThread);
}
else
{
pTask->Release();
}
} while (--n);
pTask->Release();
}
}
can somebody explain me the following code please :
this.Invoke((MethodInvoker)delegate
{
lblNCK.Text = cncType;
});
Here is where it comes from :
string cncType;
if (objDMainCncData != null)
{
int rc = objDMainCncData.Init(objDGroupManager.Handle);
if (rc == 0)
{
cncType = objDMainCncData.GetCncIdentifier();
if (cncType != string.Empty)
{
if (cncType.ToUpper().IndexOf("+") != -1)
_bFXplus = true;
this.Invoke((MethodInvoker)delegate
{
lblNCK.Text = cncType;
});
}
}
else
{
DisplayMessage("objDMainCncData.Init() failed ! error : " + rc.ToString());
}
}
}
I don't get the use of "this.Invoke((MethodInvoker)delegate".
Thank you by advance.
Peter.
Strange that no one has answered this.
Lets take it in pieces:
this.Invoke: This is a synchronization mechanism, contained in all controls. All graphic/GUI updates, must only be executed from the GUI thread. (This is most likely the main thread.) So if you have other threads (eg. worker threads, async functions etc.) that will result in GUI updates, you need to use the Invoke. Otherwise the program will blow up.
delegate{ ... }: This is a anonymous function. You can think of it as "creating a function on the fly". (Instead of finding a space in the code, create function name, arguments etc.)
(MethodInvoker): The MethodInvoker is just the name of the delegate, that Invoke is expecting. Eg. Invoke expects to be given a function, with the same signature as the "MethodInvoker" function.
What happens, is that Invoke is given a function pointer. It wakes up the GUI thread through a mutex and tells it to executes the function (through the function pointer). The parent thread then waits for the GUI thread to finish the execution. And it's done.
In my kext's stop() function, I call iflt_detach() to detach a registered iff filter. However, it appears that (for whatever reasons), the filter's detach() function may be called outside of the stop() function. In that case, what should I do in the stop function? I can't return KERN_SUCCESS since that would cause the KEXT to get unloaded with obvious side-effects for the delayed call to the detach() function.
The following snippet is from enetlognke.c and shows the stop() function:
kern_return_t com_dts_apple_kext_enetlognke_stop (kmod_info_t * ki, void * d)
{
kern_return_t retval = KERN_FAILURE; // default result, unless we know that we are
// detached from the interface.
if (gFilterRegistered == FALSE)
return KERN_SUCCESS;
if (gUnregisterProc_started == FALSE)
{
// only want to start the detach process once.
iflt_detach(gEnetFilter);
gUnregisterProc_started = TRUE;
}
if (gUnregisterProc_complete)
{
retval = KERN_SUCCESS;
}
else
{
el_printf("enetlognke_stop: incomplete\n");
}
if (retval == KERN_SUCCESS)
{
// Free KEXT resources
}
return retval;
}
gUnregisterProc_complete is set to TRUE from within this module's dispatch() function. So, if that function call is delayed (and gUnregisterProc_complete is FALSE), the stop function would veto the unload by returning KERN_FAILURE.
So, my questions are:
If KERN_FAILURE is returned, will the kernel call the KEXT's stop() function again? If not, what triggers a retry of the KEXT unload and the call to the stop() function?
Is KERN_FAILURE the correct code to return is the filter has not been detached?
Presumably, the detach function will in this case be called on another thread, once there are no threads remaining running your callbacks?
If so, this becomes a fairly straightforward thread synchronisation problem. Set up a flag variable, e.g. has_detached and protect it by a recursive mutex.
In the stop function: Lock the mutex before calling iflt_detach(). If on return, the flag hasn't been set, sleep on the flag's address while suspending the mutex, until the flag is set. Finally, unlock, and return from the stop function.
At the very end of your detach function: lock the mutex, set the flag, send a wakeup to the potentially sleeping thread and unlock. If the unlock call is in the tail position, there is no race condition between executing your detach function's code and unloading said code.
Effectively, this will block the unloading of the kext until your filter has fully detached.
Note: I haven't tried this in this particular case of network filters (I have yet to write a filter kext), but it's generally a pattern I've used a lot in other kexts.
Note 2: I say use a recursive lock to guard against deadlock in case your detach function does get called on the same thread while inside iflt_detach().
I am attempting to use boost::asio to read and write from a device on a serial port. Both boost::asio:read() and boost::asio::serial_port::read_some() block when there is nothing to read. Instead I would like to detect this condition and write a command to the port to kick-start the device.
How can I either detect that no data is available?
If necessary I can do everything asynchronously, I would just rather avoid the extra complexity if I can.
You have a couple of options, actually. You can either use the serial port's built-in async_read_some function, or you can use the stand-alone function boost::asio::async_read (or async_read_some).
You'll still run into the situation where you are effectively "blocked", since neither of these will call the callback unless (1) data has been read or (2) an error occurs. To get around this, you'll want to use a deadline_timer object to set a timeout. If the timeout fires first, no data was available. Otherwise, you will have read data.
The added complexity isn't really all that bad. You'll end up with two callbacks with similar behavior. If either the "read" or the "timeout" callback fires with an error, you know it's the race loser. If either one fires without an error, then you know it's the race winner (and you should cancel the other call). In the place where you would have had your blocking call to read_some, you will now have a call to io_svc.run(). Your function will still block as before when it calls run, but this time you control the duration.
Here's an example:
void foo()
{
io_service io_svc;
serial_port ser_port(io_svc, "your string here");
deadline_timer timeout(io_svc);
unsigned char my_buffer[1];
bool data_available = false;
ser_port.async_read_some(boost::asio::buffer(my_buffer),
boost::bind(&read_callback, boost::ref(data_available), boost::ref(timeout),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
timeout.expires_from_now(boost::posix_time::milliseconds(<<your_timeout_here>>));
timeout.async_wait(boost::bind(&wait_callback, boost::ref(ser_port),
boost::asio::placeholders::error));
io_svc.run(); // will block until async callbacks are finished
if (!data_available)
{
kick_start_the_device();
}
}
void read_callback(bool& data_available, deadline_timer& timeout, const boost::system::error_code& error, std::size_t bytes_transferred)
{
if (error || !bytes_transferred)
{
// No data was read!
data_available = false;
return;
}
timeout.cancel(); // will cause wait_callback to fire with an error
data_available = true;
}
void wait_callback(serial_port& ser_port, const boost::system::error_code& error)
{
if (error)
{
// Data was read and this timeout was canceled
return;
}
ser_port.cancel(); // will cause read_callback to fire with an error
}
That should get you started with only a few tweaks here and there to suit your specific needs. I hope this helps!
Another note: No extra threads were necessary to handle callbacks. Everything is handled within the call to run(). Not sure if you were already aware of this...
Its actually a lot simpler than the answers here have implied, and you can do it synchronously:
Suppose your blocking read was something like this:
size_t len = socket.receive_from(boost::asio::buffer(recv_buf), sender_endpoint);
Then you replace it with
socket.non_blocking(true);
size_t len = 0;
error = boost::asio::error::would_block;
while (error == boost::asio::error::would_block)
//do other things here like go and make coffee
len = socket.receive_from(boost::asio::buffer(recv_buf), sender_endpoint, 0, error);
std::cout.write(recv_buf.data(), len);
You use the alternative overloaded form of receive_from which almost all the send/receive methods have. They unfortunately take a flags argument but 0 seems to work fine.
You have to use the free-function asio::async_read.