views:

311

answers:

3

I'm making a dll that has to respond to an application's requests. One of the application's requirements is that a call should not take long to complete.

Say, I have a function foo(), which is called by the host application:

int foo(arg){
// some code i need to execute, say,
LengthyRoutine();
return 0;
}

Lets say, foo has to perform a task (or call a function) that is certain to take a long time. The application allows me to set a wait variable; if this variable is non-zero when foo returns, it calls foo again and again (resetting the wait variable before each call) until wait is returned 0.

What's the best approach to this?

Do I go:

int foo(arg){

    if (inRoutine == TRUE) {
        wait = 1;
        return 0;
    } else {
        if (doRoutine == TRUE) {
             LengthyRoutine();
             return 0;
        }
    }

    return 0;
}

This doesn't really solve the problem that LengthyRoutine is gonna take a long time to complete. Should I spawn a thread of some sort that updates inRoutine depending on whether or not it has finished its task?

Thanks..

+6  A: 

Spawning another thread is pretty much the best way to do it, just make sure you set the result variables before you set the variable that says you're finished to avoid race conditions. If this is called often you might want to spawn a worker thread ahead of time and reuse it to avoid thread start overhead.

There is another possible solution, do part of the work each time the function is called, however this spends more time in the DLL and probably isn't optimal, as well as being more complex to implement the worker code for most algos.

Eric
Thanks Eric. I've never tried to make threads before and feel like this is quite tricky to get right. I'll give it a shot :)
krebstar
This is absolutely the best option, but as Eric has said, be careful with thread synchronization
RobS
I'm not quite aware of the issues of thread synchronization yet. I just need a single worker thread that performs the routine, updates status variables at certain points throughout execution. The calling app then checks these variables periodically to know what to do. Is this ok? Are there any ...
krebstar
... issues here that I have to be aware of? Should I use MFC CreateThread? Thanks..
krebstar
Synchronization shouldn't be a major issue as long as it doesn't matter what point in the worker function the variables are read from, (if it's just progress percentage i wouldn't worry about it much) if this is an issue a simple lock will probably work fine.
Eric
You will have to be careful with threads though, as the thread will have to be created and destroyed. Look into DLL_PROCESS_DETACH and friends. Threads in a DLL are hard to do right. Maybe you should use an external helper program instead of a thread.
mghie
A: 

If incredible rare situation where LengthyRoutine() isn't 3rd party code and you have all the source and it's possible to split it up then you can consider using coroutines.

neoneye
Well, LengthyRoutine is actually a group of calls to third party code; it IS possible to split up the tasks. However, the reason for the long time it takes to complete is because it is IO-bound (waiting for another component to finish its task).. Sorry I didn't explain this in my question..
krebstar
ok, sounds like you need a separate thread or process then :-)
neoneye
+1  A: 

If C programming, use callback - pass the callback to foo. You have to agree on the callback signature and do some housekeeping to trigger it when the work in LengthyRoutine is done.

typedef (void) callbackFunction(void);

int foo(arg, callbackFunction)
{
   // some code i need to execute, say,
   // register callback and return right away
   // Trigger the LengthyRoutine to run after this function returns

   return 0;
}

LengthyRoutine()
{
   // do lenghty routine

   // now inform the caller with their suppiled callback
   callbackFunction();
}

Essentially Observer Pattern in C. C++ makes the work a lot easier/cleaner in my opinion

MeThinks
This seems like a viable option. I don't know much about callbacks yet, but it seems easier to implement as opposed to threads.. +1
krebstar
@krebstar: Please note that a callback mechanism does not remove the need for a worker thread - it just replaces the need for multiple calls to the function until lengthy process has finished. You *will* need a worker thread.
mghie