Syntax
int _rmem_init(void); /* no header file - defined in run-time startup code */Description
By default, all DLLs call The Developer's Toolkit _DLL_InitTerm function, which in turn calls _rmem_init for you. However, if you are writing your own subsystem _DLL_InitTerm function (for example, to perform actions other than memory initialization and termination), you must call _rmem_init from your version of _DLL_InitTerm before you can call any other library functions.
If your DLL contains C++ code, you must also call __ctordtorInit after _rmem_init to ensure that static constructors and destructors are initialized properly. __ctordtorInit is defined in the run-time startup code as:
void __ctordtorInit(void);
If the memory functions were successfully initialized, _rmem_init returns 0. A return code of -1 indicates an error. If an error occurs, an error message is written to file handle 2, which is the usual destination of stderr.
The following example shows the _DLL_InitTerm function from The Developer's Toolkit sample program for building subsystem DLLs, which calls _rmem_init to initialize the memory functions.
#pragma strings( readonly )
/******************************************************************************/
/* */
/* _DLL_InitTerm - Initialization/Termination function for the DLL that is */
/* invoked by the loader. */
/* */
/* DLLREGISTER - Called by _DLL_InitTerm for each process that loads the */
/* DLL. */
/* */
/* 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>
unsigned long _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 */
/* _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;
}
/* 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;
}
Related Information