home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
VSCPPv8.zip
/
VACPP
/
IBMCPP
/
samples
/
COMPILER
/
SAMPLE05
/
DLL
/
SAMPLE05.C
next >
Wrap
Text File
|
1995-03-22
|
12KB
|
307 lines
#pragma strings( readonly )
/******************************************************************************/
/* */
/* SAMPLE05.C */
/* */
/* COPYRIGHT: */
/* ---------- */
/* Copyright (C) International Business Machines Corp., 1991, 1993. */
/* */
/* DISCLAIMER OF WARRANTIES: */
/* ------------------------- */
/* The following [enclosed] code is sample code created by IBM */
/* Corporation. This sample code is not part of any standard IBM product */
/* and is provided to you solely for the purpose of assisting you in the */
/* development of your applications. The code is provided "AS IS", */
/* without warranty of any kind. IBM shall not be liable for any damages */
/* arising out of your use of the sample code, even if they have been */
/* advised of the possibility of such damages. */
/* */
/* This example provides 5 external entrypoints of which 2 are exported for */
/* use by client processes. The entrypoints are: */
/* */
/* _DLL_InitTerm - Initialization/Termination function for the DLL that is */
/* invoked by the loader. When the /Ge- compile option is */
/* used the linker is told that this is the function to */
/* execute when the DLL is first loaded and last freed for */
/* each process. */
/* */
/* DLLREGISTER - Called by _DLL_InitTerm for each process that loads the */
/* DLL. */
/* */
/* DLLINCREMENT - Accepts a count from its client and adds this value to */
/* the process and system totals. */
/* */
/* DLLSTATS - Dumps process and system totals on behalf of its client. */
/* */
/* DLLDEREGISTER- Called by _DLL_InitTerm for each process that frees the */
/* DLL. */
/* */
/******************************************************************************/
#define INCL_DOS
#define INCL_DOSERRORS
#define INCL_NOPMAPI
#include <os2.h>
#include <stdio.h>
#include "sample05.h"
unsigned long _System _DLL_InitTerm( unsigned long hModule, unsigned long ulFlag );
static unsigned long DLLREGISTER( void );
static unsigned long DLLDEREGISTER( void );
#define SHARED_SEMAPHORE_NAME "\\SEM32\\SAMPLE05\\DLL.LCK"
/* The following data will be per-process data. It will not be shared among */
/* different processes. */
static HMTX hmtxSharedSem; /* Shared semaphore */
static ULONG ulProcessTotal; /* Total of increments for a process */
static PID pidProcess; /* Process identifier */
/* This is the global data segment that is shared by every process. */
#pragma data_seg( GLOBAL_SEG )
static ULONG ulProcessCount; /* total number of processes */
static ULONG ulGrandTotal; /* Grand total of increments */
/* _DLL_InitTerm() - called by the loader for DLL initialization/termination */
/* This function must return a non-zero value if successful and a zero value */
/* if unsuccessful. */
unsigned long _DLL_InitTerm( unsigned long hModule, unsigned long ulFlag )
{
APIRET rc;
/* If ulFlag is zero then initialization is required: */
/* If the shared memory pointer is NULL then the DLL is being loaded */
/* for the first time so acquire the named shared storage for the */
/* process control structures. A linked list of process control */
/* structures will be maintained. Each time a new process loads this */
/* DLL, a new process control structure is created and it is inserted */
/* at the end of the list by calling DLLREGISTER. */
/* */
/* If ulFlag is 1 then termination is required: */
/* Call DLLDEREGISTER which will remove the process control structure */
/* and free the shared memory block from its virtual address space. */
switch( ulFlag )
{
case 0:
if ( !ulProcessCount )
{
_rmem_init();
/* Create the shared mutex semaphore. */
if ( ( rc = DosCreateMutexSem( SHARED_SEMAPHORE_NAME,
&hmtxSharedSem,
0,
FALSE ) ) != NO_ERROR )
{
printf( "DosCreateMutexSem rc = %lu\n", rc );
return 0;
}
}
/* Register the current process. */
if ( DLLREGISTER( ) )
return 0;
break;
case 1:
/* De-register the current process. */
if ( DLLDEREGISTER( ) )
return 0;
_rmem_term();
break;
default:
return 0;
}
/* Indicate success. Non-zero means success!!! */
return 1;
}
/* DLLREGISTER - Registers the current process so that it can use this */
/* subsystem. Called by _DLL_InitTerm when the DLL is first */
/* loaded for the current process. */
static unsigned long DLLREGISTER( void )
{
APIRET rc;
PTIB ptib;
PPIB ppib;
/* Get the address of the process and thread information blocks. */
if ( ( rc = DosGetInfoBlocks( &ptib, &ppib ) ) != NO_ERROR )
{
printf( "DosGetInfoBlocks rc = %lu\n", rc );
return rc;
}
/* Open the shared mutex semaphore for this process. */
if ( ( rc = DosOpenMutexSem( SHARED_SEMAPHORE_NAME,
&hmtxSharedSem ) ) != NO_ERROR )
{
printf( "DosOpenMutexSem rc = %lu\n", rc );
return rc;
}
/* Acquire the shared mutex semaphore. */
if ( ( rc = DosRequestMutexSem( hmtxSharedSem,
SEM_INDEFINITE_WAIT ) ) != NO_ERROR )
{
printf( "DosRequestMutexSem rc = %lu\n", rc );
DosCloseMutexSem( hmtxSharedSem );
return rc;
}
/* Increment the count of processes registered. */
++ulProcessCount;
/* Initialize the per-process data. */
ulProcessTotal = 0;
pidProcess = ppib->pib_ulpid;
/* Tell the user that the current process has been registered. */
printf( "\nProcess %lu has been registered.\n\n", pidProcess );
/* Release the shared mutex semaphore. */
if ( ( rc = DosReleaseMutexSem( hmtxSharedSem ) ) != NO_ERROR )
{
printf( "DosReleaseMutexSem rc = %lu\n", rc );
return rc;
}
return 0;
}
/* DLLINCREMENT - Increments the process and global totals on behalf of the */
/* calling program. */
int DLLINCREMENT( int incount )
{
APIRET rc; /* return code from DOS APIs */
/* Acquire the shared mutex semaphore. */
if ( ( rc = DosRequestMutexSem( hmtxSharedSem,
SEM_INDEFINITE_WAIT ) ) != NO_ERROR )
{
printf( "DosRequestMutexSem rc = %lu\n", rc );
return rc;
}
/* Increment the counts the process and grand totals. */
ulProcessTotal += incount;
ulGrandTotal += incount;
/* Tell the user that the increment was successful. */
printf( "\nThe increment for process %lu was successful.\n\n", pidProcess );
/* Release the shared mutex semaphore. */
if ( ( rc = DosReleaseMutexSem( hmtxSharedSem ) ) != NO_ERROR )
{
printf( "DosReleaseMutexSem rc = %lu\n", rc );
return rc;
}
return 0;
}
/* DLLSTATS - Prints process and grand totals. */
int DLLSTATS( void )
{
APIRET rc;
/* Acquire the shared mutex semaphore. */
if ( ( rc = DosRequestMutexSem( hmtxSharedSem,
SEM_INDEFINITE_WAIT ) ) != NO_ERROR )
{
printf( "DosRequestMutexSem rc = %lu\n", rc );
return rc;
}
/* Print out per-process and global information. */
printf( "\nCurrent process identifier = %lu\n", pidProcess );
printf( "Current process total = %lu\n", ulProcessTotal );
printf( "Number of processes registered = %lu\n", ulProcessCount );
printf( "Grand Total = %lu\n\n", ulGrandTotal );
/* Release the shared mutex semaphore. */
if ( ( rc = DosReleaseMutexSem( hmtxSharedSem ) ) != NO_ERROR )
{
printf( "DosReleaseMutexSem rc = %lu\n", rc );
return rc;
}
return 0;
}
/* DLLDEREGISTER - Deregisters the current process from this subsystem. */
/* Called by _DLL_InitTerm when the DLL is freed for the */
/* last time by the current process. */
static unsigned long DLLDEREGISTER( void )
{
APIRET rc;
/* Acquire the shared mutex semaphore. */
if ( ( rc = DosRequestMutexSem( hmtxSharedSem,
SEM_INDEFINITE_WAIT ) ) != NO_ERROR )
{
printf( "DosRequestMutexSem rc = %lu\n", rc );
return rc;
}
/* Decrement the count of processes registered. */
--ulProcessCount;
/* Tell the user that the current process has been deregistered. */
printf( "\nProcess %lu has been deregistered.\n\n", pidProcess );
/* Release the shared mutex semaphore. */
if ( ( rc = DosReleaseMutexSem( hmtxSharedSem ) ) != NO_ERROR )
{
printf( "DosReleaseMutexSem rc = %lu\n", rc );
return rc;
}
/* Close the shared mutex semaphore for this process. */
if ( ( rc = DosCloseMutexSem( hmtxSharedSem ) ) != NO_ERROR )
{
printf( "DosCloseMutexSem rc = %lu\n", rc );
return rc;
}
return 0;
}