views:

415

answers:

2

I'm currently writing a wrapper library for windows mobile in C/C++. I have to implement and export the following functions:

void start_scanning();
int wait_for_scanning_result();
void stop_scanning();

start_scanning() is called to start the scanning process. wait_for_scanning_result() will wait until a result is available and return it, and stop_scanning will abort the process.

The library I am using has a callback function that is executed when a result is available.

void on_scanning_result(int result)
{
   /* My code goes here */
}

Unfortunately I have to implement the functions above, so my plan was to solve it like this:

void on_scanning_result(int result)
{
   scan_result_available = 1;
   scan_result = result;
}

int wait_for_scanning_result()
{
   /* ... wait until scan_result_available == 1 */
   return scan_result;
}

I have no idea how to do this in windows/C and I would be very glad if someone could help me or tell me which functions I have to use to accomplish this.

A: 

Something like this, I expect:

//declare as volatile to inform C that another thread
//may change the value
volatile int scan_result_available;

int wait_for_scanning_result()
{
    while(scan_result_available == 0) {
        //do nothing
    }
    return scan_result;
}

You should find out whether the callback runs in another thread, or runs asynchronously in the same thread, or whether the library needs some other means to allow the callback to run.

Artelius
Is there something beside waiting in a loop that I could do? I expected something like semaphores.
xsl
Yes, there is, but I'm afraid I'm not familiar with Windows Mobile.
Artelius
Actually, this would be a fairly stupid idea to do. I'm not aware of any multi-core CPU for the WM platform, so when this loop runs it prevents the other code from running, and thus scan_result_available doesn't change (!)
MSalters
Er, what? You can run multiple threads on single-core processors. The code I posted is a decidedly BAD solution, but I'm pretty sure it would work.
Artelius
There must be a sleep() instruction inside a loop, forcing current thread to sleep and don't waste processor time. This will give time for other threads to change the scan_result_variable. Otherwise, current thread will waste processor time, doing nothing. That is what MSalters was going to say, I guess...
SadSido
Not really, even without the sleep other thrads and processes run perfectly well. admittedly a sleep would make it run better in that the active thread would be yielded more often.
Elemental
+3  A: 

You can use windows Synchronization Functions.

Basically all you have to do is:
* CreateEvent - create an event
* WaitForSingleObject - wait for this event to become signaled
* SetEvent - signal the event

Cristian Adam
+1. These functions exist exactly for these purposes. Unfortunately, the Event objects may be heavyweight. For the question, interlocked increments and decrements (and wait()) may do the job...
SadSido
As SadSido says this is a correct way but perhaps a bit heavy - windows' critical sections functions could also be used here.
Elemental
Events are very basic synchronization objects, supported from Windows CE 1.0, they should be very fast. Any benchmarks to prove otherwise?
Cristian Adam
@Christian Adam: Thank you. With your help I was able to finish the wrapper library. I didn't notice any performance problems and createevent/setevent/waitforsingleobject were quite easy to use.
xsl