/* * Manual page at process.def */ INT32 CGEN_PUBLIC CProcess::Start() { const SMic* pMic = NULL; // Method invocation context of Start() CFunction* iCaller = NULL; // Function calling Start() CFunction* iFnc = NULL; // Process function StkItm* pStkItm = NULL; // Stack item INT32 nArgs = 0; // Number of process function arguments // Validate and initialize // ------------------------------------ if (m_nState!=0) // Not virginal return IERROR(this,PRC_CANTSTART,"multiple starts not allowed",0,0); // Forget it! if (!(pMic = CDlpObject_MicGet(_this))) return -1; // Get method invocation context iCaller = (CFunction*)CDlpObject_OfKind("function",pMic->iCaller); // Get calling CFunction if (!iCaller) return -1; // Must be a function! // Initialize process // ------------------------------------ sprintf(m_psTmpFile,"%s%ld",dlp_tempnam(NULL,"~dLabPro#process#"),(long)dlp_time());// Initialize temp. file name prefix // Marshal arguments // ------------------------------------ if (!(pStkItm=iCaller->StackGet(0))) return IERROR(this,PRC_TOOFEWARGS,0,0,0);// Get stack top if (pStkItm->nType==T_INSTANCE) // Stack top is an instance iFnc = (CFunction*)CDlpObject_OfKind("function",pStkItm->val.i); // Get function to be called if (iFnc) // This process is a function call { // >> IFIELD_RESET(CDlpObject,"dto"); // Create data transfer object nArgs = CData_GetNRecs(iFnc->m_idArg); // Get number of function arguments Marshal(m_iDto,iCaller,nArgs); // Marshal arguments for transfer } // << else // This process is a program call dlp_strcpy(m_psCmdLine,iCaller->PopString(0)); // Get program command line #ifdef USE_FORK if (iFnc) // This process is a function call { // >> m_hPid=fork(); // Fork the process if(m_hPid>0){ // Parent process >> m_nState |= PRC_DATASENT; // Remember data have been sent m_nState |= PRC_RUNNING; // Set running flag m_hThread = 0; // Clear thread handle return O_K; // Everything is fine } // << if(m_hPid==0) return DoJobFork(iCaller,iFnc); // The child process runs the function return IERROR(this,PRC_CANTSTART,"fork() failed",0,0); // On error (fid<0) we return } // << #endif // Start job in watcher thread // ------------------------------------ m_hPid = 0; // Reset process id SendData(); // Send transfer data m_hThread = dlp_create_thread(DoJob,this); // Do the job and watch it return O_K; // Yo! }
/* * Manual page at process.def */ INT16 CGEN_PUBLIC CProcess::MarshalRetval() { CDlpObject* iDto = NULL; // Data transfer object const SMic* pMic = NULL; // Current method invocation context CFunction* iCaller = NULL; // Calling function StkItm* pStkItm = NULL; // Stack item to marshal // Validate and initialize // ------------------------------------ if (!(pMic = CDlpObject_MicGet(_this))) return -1; // Get method invocation context iCaller = (CFunction*)CDlpObject_OfKind("function",pMic->iCaller); // Get calling CFunction if (!iCaller) return -1; // Must be a function! // Pack second stack element into the CDlpObject on the stack top // ------------------------------------ iDto = iCaller->PopInstance(0); // Get instance on stack top if (!iDto) return NOT_EXEC; // No instance on stack top --> puuh! if (iCaller->StackGetLength()==0) return O_K; // Nothing more on the stack --> ok pStkItm = iCaller->StackGet(0); // Get stack top Pack(iDto,NULL,pStkItm,PRC_S_RETV); // Pack it as "~iRetv" iCaller->Pop(0); // Remove stack top return O_K; // Ok }