⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 omnipartcl.cc

📁 编译工具
💻 CC
字号:
//// omniParTcl.cc// // Implementation of loosely synchronized parallel C++ and Tcl/Tk threads, // for use in particular to create GUIs for Orbix applications.  This is// version II which is more lightweight, allows the developer to write// his or her own main() if desired, and provides a C++ class for Tcl Dstring// manipulation.//// $Id: omniParTcl.cc,v 1.4.10.1 2001/06/18 20:28:54 sll Exp $ $Author: sll $// #include <stdlib.h>#include <unistd.h>#include <string.h>#include <strstream.h>#include <iostream.h>#include "omniParTcl.h"#include "scriptQueue.h"//// We use a pipe to allow the C++ threads to signal asynchronously// to Tcl/Tk that there is something to do.  We mutex-protect access// to the pipe.//static int        tclWakeupPipe[2];static omni_mutex twpMutex;//// We maintain a FIFO queue of Tcl/Tk scripts waiting for evaluation.// Note that the script queue copies the script names, so the two// omniParTcl functions can be called with constant strings.  We// mutex-protect access to the script queue.//static scriptQueue sQ;static omni_mutex  sqMutex;void omniTclMeAndWait(char *script){  //  // Arrange to have the given script evaluated by Tcl/Tk, and don't  // return until the script has been evaulated.  //  char dummybyte; // We can write any old byte to the pipe    omni_condition sqeCond(&sqMutex);      sqMutex.acquire();    sQ.enq(script,&sqeCond);                 // Put script on queue of those                                           // waiting for eval.  twpMutex.acquire();  write(tclWakeupPipe[1],&dummybyte,1);    // Wake up Tcl/Tk  twpMutex.release();    sqeCond.wait();                          // Wait for Tcl/Tk to finish with                                           // this script.  sqMutex.release();                       // Release the lock on the queue}  void omniTclMeAndRun(char *script){  //  // Arrange to have the given script evaluated by Tcl/Tk, and return  // immediately.  //  char dummybyte; // We can write any old byte to the pipe    sqMutex.acquire(); //  sQ.enq(script,0);   // Put script on queue of those waiting for eval.  sqMutex.release(); //  twpMutex.acquire();  write(tclWakeupPipe[1],&dummybyte,1);    // Wake up Tcl/Tk  twpMutex.release();}  void cxxTclScriptHandler(ClientData clientData, int mask){  //  // This is invoked by Tcl/Tk whenever there is something to read on  // tclWakeupPipe[0].  This will only be the case when at least one C++   // thread has called one of the above omniParTcl functions.  There may   // be more than one script awaiting evaluation, and we evaluate all of   // them.  //  Tcl_Interp *interp = (Tcl_Interp *) clientData;  scriptcondpair scp;  char sink;    if (mask != TK_READABLE) {    cerr << "omniParTcl: unexpected state of tclWakeupPipe." << endl;    ::exit(1);  }  int done = 0;  while (!done) {        sqMutex.acquire();  //    scp = sQ.deq();      // Get next script/condition pair.    sqMutex.release();  //    if (scp.script == (char *)0) {      done = 1;    }    else {      //      // Consume the trigger input:      //      read(tclWakeupPipe[0],&sink,1);       //      // Evaluate the script:      //      int rc = Tcl_GlobalEval(interp, scp.script);      if (rc != TCL_OK) {        cerr << "omniParTcl: error evaluating Tcl/Tk script \""             << scp.script << "\"" << endl;        cerr << interp->result << endl;        ::exit(1);      }      //      // Reclaim the string storage:      //      delete scp.script;      //      // Wake up the C++ thread if it's waiting.      //      if (scp.cond != 0) {        sqMutex.acquire();        scp.cond->signal();        sqMutex.release();       }    }  }}int threadSafeExec(ClientData clientData, Tcl_Interp *interp,                   int argc, char *argv[]){  //  // Tcl's exec command uses vfork which is not thread-safe and therefore  // not omniParTcl-safe either.  Use threadSafeExec instead.  //  int i;    if (argc < 2) {    Tcl_SetResult(interp, "omniParTcl: threadSafeExec requires an argument",                  TCL_VOLATILE);    return TCL_ERROR;  }  int cmdlen = 0;  for (i = 1; i < argc; i++) {    cmdlen += strlen(argv[i]) + 1;  }    cmdlen += 1;  char *cmd = new char[cmdlen];  ostrstream cmdos(cmd,cmdlen);  for (i = 1; i < argc; i++) {    cmdos << argv[i] << " ";  }  cmdos << ends;  system(cmd);  delete cmd;  return TCL_OK;}  int omniParTcl_Init(Tcl_Interp *interp){  //  // omniParTcl initialization.  To be called from Tcl_AppInit().  //  //  // We use Tcl/Tk's file event callbacks to allow C++ to invoke  // Tcl/Tk commands asynchronously.  //    if (pipe(tclWakeupPipe) != 0) {    Tcl_SetResult(interp, "omniParTcl: cannot create tclWakeupPipe", TCL_VOLATILE);    return TCL_ERROR;  }    Tk_CreateFileHandler(tclWakeupPipe[0], TK_READABLE,                        (Tk_FileProc *) cxxTclScriptHandler,                       (ClientData) interp);  //  // Provide a thread-safe exec since Tcl doesn't.  //  Tcl_CreateCommand(interp, "threadSafeExec", threadSafeExec,                    (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);  return TCL_OK;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -