Jump to content

DosFlagProcess

From EDM2
Revision as of 00:32, 5 October 2023 by Ak120 (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Legacy Function Warning
It is recommended to use a newer replacement for this function.
Replacement: N/A
Remarks: This function has been eliminated since OS/2 2.0. [1]

This call allows one process to set an external event flag for another.

Syntax

DosFlagProcess (ProcessID, ActionCode, Flagnum, Flagarg)

Parameters

ProcessID (PID) - input
ID of the process or root process of the process tree, who is to receive notification that the flag event has occurred.
ActionCode (USHORT) - input
Indicates who is to receive notification that the flag event has occurred.
0 - The indicated process and all its descendant processes are flagged. (Detached processes cannot be flagged.) The indicated process must be the current process or one it has created as a non-detached process. If the indicated process terminates, its descendants are still flagged.
1 - Only the indicated process is flagged. Any process can be specified.
Flagnum (USHORT) - input
Number of the flag event whose occurrence is to be signalled, as shown below:
0 Flag A
1 Flag B
2 Flag C.
Flagarg (USHORT) - input
An argument passed to indicated processes.

Return Code

rc (USHORT) - return
Return code descriptions are:
  • 0 NO_ERROR
  • 1 ERROR_INVALID_FUNCTION
  • 156 ERROR_SIGNAL_REFUSED
  • 186 ERROR_INVALID_FLAG_NUMBER
  • 303 ERROR_INVALID_PROCID

Remarks

A process issues DosFlagProcess to set one of three user-defined flags available to the process. The meaning of the flag is defined by the flag user - the process that receives the signal generated by the OS/2 signal mechanism upon the setting of the flag.

When the flag user is signaled, its reaction to the signal depends on values it has specified with DosSetSigHandler. For example, it can respond by giving control to a signal handler it has registered with DosSetSigHandler for the signal that corresponds to the user flag (SIGPFA corresponds to Flag A, and so on). Or, the flag user can ignore the signal and return an error code to the flagger.

If no action is specified with DosSetSigHandler by a process for a user flag, the default is to ignore the signal.

Bindings

C

#define INCL_DOSSIGNALS

USHORT  rc = DosFlagProcess(ProcessID, ActionCode, Flagnum, Flagarg);

PID     ProcessID;     /* Process ID to flag */
USHORT  ActionCode;    /* Indicate to flag descendants */
USHORT  Flagnum;       /* Flag number */
USHORT  Flagarg;       /* Flag argument */

USHORT  rc;            /* return code */

MASM

EXTRN  DosFlagProcess:FAR
INCL_DOSSIGNALS     EQU 1

PUSH   WORD    ProcessID     ;Process ID to flag
PUSH   WORD    ActionCode    ;Indicate to flag descendants
PUSH   WORD    Flagnum       ;Flag number
PUSH   WORD    Flagarg       ;Flag argument
CALL   DosFlagProcess

Returns WORD

Example

This example starts a program named 'simple2.exe', and then signals the program with the external flag A.

#define INCL_DOSPROCESS
#define INCL_DOSSIGNALS

#define PROGRAM_NAME "simple2.exe"

CHAR        LoadError[100];
PSZ         Args;
PSZ         Envs;
RESULTCODES ReturnCodes;
USHORT      FlagArg;
USHORT      rc;

   FlagArg = 2;

   if(!DosExecPgm(LoadError,             /* Object name buffer */
                  sizeof(LoadError),     /* Length of object name buffer */
                  EXEC_ASYNC,            /* Asynchronous/Trace flags */
                  Args,                  /* Argument string */
                  Envs,                  /* Environment string */
                  &ReturnCodes,          /* Termination codes */
                  PROGRAM_NAME))         /* Program file name */
      rc = DosFlagProcess(ReturnCodes.codeTerminate,  /* Process ID to
                                                          flag */
                          FLGP_PID,                   /* Indicate to flag
                                                             descendants */
                          PFLG_A,                     /* Flag number */
                          FlagArg);                   /* Flag argument */

The following example illustrates the use of a user-defined flag to signal time-critical events. The main thread installs a routine, named FlagA_Handler(), as the signal handler for user-defined Flag A. It then creates a thread and blocks on a reserved RAM semaphore; this thread obtains its process ID and signals the main thread via Flag A. The main thread responds by executing the signal handler.

#define INCL_DOSPROCESS
#define INCL_DOSSIGNALS
#define INCL_DOSERRORS

#include <os2.h>

#define TIMEOUT           5000L

TID         ThreadID;
BYTE        ThreadStack[4000];

VOID APIENTRY FlagA_Handler(arg1, arg2)       /* Define signal handler */
  USHORT      arg1;
  USHORT      arg2;
{
  printf("Handler for Flag A now running.\n");
  return;
}

VOID APIENTRY Thread_A()
{
  PIDINFO     PidInfo;
  USHORT      FlagArg;
  USHORT      rc;

  DosGetPID(&PidInfo);
  printf("Process ID is %d\n", PidInfo.pid);
  if(!(rc = DosFlagProcess(PidInfo.pid,
                           FLGP_PID,
                           PFLG_A,
                           FlagArg)))
    printf("FlagA signal sent from ThreadA to main thread.\n");
  else
    printf("FlagProcess rc is %d\n", rc)/* Error processing on rc */;
  DosExit(EXIT_THREAD,                 /* Action Code */
          RETURN_CODE);                /* Result Code */
}

main()
{
  ULONG            RamSem = 0L;
  ULONG far        *RamSemHandle = &RamSem;
  USHORT           rc;

  if(!(rc=DosSetSigHandler((PFNSIGHANDLER) FlagA_Handler,
                           NULL,
                           NULL,
                           SIGA_ACCEPT,
                           SIG_PFLG_A)))
    printf("Main thread has set FlagA handler.\n");
  else

    /* Error processing on rc */;
  if(!(rc=DosSemRequest(RamSemHandle,
                        TIMEOUT)))
    printf("Semaphore obtained.\n");
  if(!(DosCreateThread((PFNTHREAD) Thread_A,
                        &ThreadID,
                        &ThreadStack[3999])))
    printf("ThreadA created.\n");
  printf("Main thread will now wait on a Ramsem for a while.\n");
  if((rc=DosSemRequest(RamSemHandle,
                       TIMEOUT))
       == ERROR_INTERRUPT)
  printf("Main thread interrupted while waiting, rc is %d.\n", rc);
}