waiting for a wxProcess

If you are using wxDev-C++ for your wxWidgets design, please ask your questions here instead of in IDE Related.
Post Reply
noorez
Knows some wx things
Knows some wx things
Posts: 42
Joined: Sat Nov 04, 2006 4:17 am

waiting for a wxProcess

Post by noorez »

How can I wait for a process to finish before starting a new one. Here is what I'm doing:

Code: Select all

for(...){
...
encryptDlg->done = false;

    wxProcess* encryptProcess = new wxProcess(encryptDlg, 1);
    encryptProcess->Redirect();
    int exec = ::wxExecute(command,wxEXEC_ASYNC,encryptProcess);

    if(exec == 0)
     ::wxMessageBox(wxT("Could not start encrypt process"));


    //wxInputStream* inputStream = encryptProcess->GetInputStream();
    wxOutputStream* outputStream = encryptProcess->GetOutputStream();

    if(outputStream == NULL)
      ::wxMessageBox(wxT("No output stream"));

    outputStream->Write(cryptSettings.getKey().c_str(),cryptSettings.getKey().Length());


    while(!encryptDlg->done);
...
}
The encryptDlg->done variable is changed when the event is fired signaling the end of the process in the
EncryptDlg::ProcessDone(){
done = true;
}

However, I found that the while loop freezes the program.

In Java, and for those of you who know java, I would have done something like this


//main thread object
synchronize(this){
new MyThread(this).start();
wait();
}

//sub thread
MyThread::run()
{
doEncryption();
synchronize(mainThread){
mainThread.notify();
}
}

How would I accomplish somethig like this in wxWidgets?
Peer Sommerlund
Knows some wx things
Knows some wx things
Posts: 43
Joined: Tue Jun 13, 2006 7:21 am
Location: Denmark
Contact:

Post by Peer Sommerlund »

Are you developing a GUI application? In this case you are probably preventing the main thread from doing anything besides waiting in your
"while(!encryptDlg->done);" loop. A solution could be to restructure the code to use events instead of polling.

I'm not sure what to do if you do not have a GUI. Maybe it will help if you call wxMilliSleep(100) or wxApp::Yield() from inside your polling loop.
noorez
Knows some wx things
Knows some wx things
Posts: 42
Joined: Sat Nov 04, 2006 4:17 am

Post by noorez »

I am doing this in a GUI.
Peer Sommerlund
Knows some wx things
Knows some wx things
Posts: 43
Joined: Tue Jun 13, 2006 7:21 am
Location: Denmark
Contact:

Post by Peer Sommerlund »

Your code seems to indicate that you want a sequential flow, where you call the external encrypt program, wait for it, then contine to the next item that needs encryption.

Why not use the syncronous version of wxExecute?

wxExecute(const wxString& command, wxArrayString& output, int flags = 0);

It will wait for the command to terminate, and give you the output in a wxArrayString.


For more ideas on how to call external programs, consult the "exec" sample in the wxWidgets distribution.
Jorg
Moderator
Moderator
Posts: 3971
Joined: Fri Aug 27, 2004 9:38 pm
Location: Delft, Netherlands
Contact:

Post by Jorg »

If you still want to have control in your application, simply create a command queue with an ID and command string. For example in a timer you execute an asynchronous wxProcess, and get the stdin back through a wxInputStream. Then when it exited with code 0 (which means all ok) execute the next command in the queue. This is how i do it with RarVision. The Scheduler puts in commands to be executed, and every 500 ms I check for a new command, and execute it when there is no active process.

Regards,
- Jorgen
Forensic Software Engineer
Netherlands Forensic Insitute
http://english.forensischinstituut.nl/
-------------------------------------
Jorg's WasteBucket
http://www.xs4all.nl/~jorgb/wb
noorez
Knows some wx things
Knows some wx things
Posts: 42
Joined: Sat Nov 04, 2006 4:17 am

Post by noorez »

Sorry, I don't think I totally understand what you mean here. For the command queue that you were talking about here? The exit code for a program, is it returned via the wxInputStream or the ::wxExecute command?
noorez
Knows some wx things
Knows some wx things
Posts: 42
Joined: Sat Nov 04, 2006 4:17 am

Post by noorez »

I'm trying to experiment with something mention in a previous process. I don't know however, if this would actually work...
Below are the classes that i've overriden for wxProcess and wxTimer.


class CryptionProcess : public wxProcess
{
private:
bool done;

public:
void OnTerminate(int pid, int status);
void restDone();
bool isDone();
};

class ProcessTimer : public wxTimer
{
private:
vector<wxString> commands;
CryptionProcess currentProcess;

public:
void Notify();
};
Post Reply