Example #1
0
/*{
** Name: DI_inc_Di_slave_cnt - Autoincrements an element in the
**			       Di_slave_cnt structure;
**
** Description:
**
** Inputs:
**	Number		Index into Di_slave_cnt array
**
** Outputs:
**	intern_status	Internal error indicating reason for failure.
**
**    Returns:
**        OK
**
**    Exceptions:
**        none
**
** Side Effects:
**        none
**
** History:
**    30-nov-1992 (rmuth)
** 	    Created.
**
*/
STATUS
DI_inc_Di_slave_cnt(
    i4		number,
    STATUS	*intern_status)
{

    STATUS    status;

    do
    {
        status = gen_Psem(&DI_sc_sem);
        if ( status != OK )
        {
            *intern_status = DI_LRU_GENPSEM_ERR;
            break;
        }

        ++Di_slave_cnt[ number ];

        status = gen_Vsem(&DI_sc_sem);
        if ( status != OK )
        {
            Di_fatal_err_occurred = TRUE;
            *intern_status = DI_LRU_GENVSEM_ERR;
            break;
        }

    } while (FALSE);

    return( status );
}
Example #2
0
/******************************************************************************
** Name: MEsmdestroy()	- Destroy a shared memory segment
**
** Description:
**	Remove the shared memory segment specified by shared memory identifier
**	"key" from the system and destroy any system data structure associated
**	with it.
**
**	Note: The shared memory pages are not necessarily removed from
**	processes which have the segment mapped.  It is up to the clients to
**	detach the segment via MEfree_pages prior to destroying it.
**
**	Protection Note: The caller of this routine must have protection to
**	destroy the shared memory segment.  Protections are enforced by the
**	underlying Operating System.  In general, this routine can only be
**	guaranteed to work when executed by a user running with the same
**	effective privledges as the user who created the shared memory segment.
**
** Inputs:
**	user_key			identifier which was previosly
**				      used in a successful MEget_pages() call
**				      (not necessarily a call in this process)
**
** Outputs:
**	err_code 		System specific error information.
**
**	Returns:
**	    OK
**	    ME_NO_PERM		    No permission to destroy shared memory
**				            segment.
**	    ME_NO_SUCH_SEGMENT	indicated shared memory segment does not
**				            exist.
**	    ME_NO_SHARED	    No shared memory in this CL.
**	    ME_BAD_ADVICE	    call was made during ME_USER_ALLOC
**
**	Exceptions:
**	    none
**
** Side Effects:
**	    none
**
******************************************************************************/
STATUS
MEsmdestroy(char        *user_key,
            CL_ERR_DESC *err_code)
{
	LOCATION        location;
	LOCATION        temp_loc;
	char            loc_buf[MAX_LOC + 1];
	STATUS          ret_val = OK;

	CLEAR_ERR(err_code);

	/*
	 * Get location of ME files for shared memory segments.
	 */

# ifdef MCT
	gen_Psem(&NM_loc_sem);
# endif /* MCT */
	ret_val = NMloc(FILES,
	                PATH,
	                (char *) NULL,
	                &temp_loc);
	if (!ret_val)
	{
		LOcopy(&temp_loc,
		       loc_buf,
		       &location);
		LOfaddpath(&location,
		           ME_SHMEM_DIR,
		           &location);
		LOfstfile(user_key,
		          &location);

		if (LOexist(&location) != OK)
			ret_val = FAIL;
		else {
			ret_val = LOdelete(&location);
			switch (ret_val) {
			case OK:
			case ME_NO_PERM:
				break;;

			default:
				ret_val = ME_NO_SUCH_SEGMENT;
				break;;
			}
		}
	}
# ifdef MCT
	gen_Vsem(&NM_loc_sem);
# endif /* MCT */
	return (ret_val);
}
Example #3
0
/******************************************************************************
**	Name:
**		MEtfree.c
**
**	Function:
**		MEtfree
**
**	Arguments:
**		i2	tag;
**
**	Result:
**		Free all blocks of memory on allocated list with
**		MEtag value of 'tag'.
**
**		Returns STATUS: OK, ME_00_PTR, ME_OUT_OF_RANGE, ME_BD_TAG,
**				ME_FREE_FIRST, ME_TR_TFREE, ME_NO_TFREE.
**
**	Side Effects:
**		None
**  History:
**	03-jun-1996 (canor01)
**	    Internally, store the tag as an i4 instead of an i2. This makes
**	    for more efficient code on byte-aligned platforms that do fixups.
**	27-may-97 (mcgem01)
**	    Clean up compiler warnings.
**
******************************************************************************/
STATUS
MEtfree(u_i2 tag)
{
	STATUS status;

	if (tag == 0)
		return ME_ILLEGAL_USAGE;

# ifdef MCT
	gen_Psem(&ME_stream_sem);
# endif /* MCT */
	status = IIME_ftFreeTag((i4)tag);
# ifdef MCT
	gen_Vsem(&ME_stream_sem);
# endif /* MCT */
	return (status);
}
Example #4
0
/*{
** Name: DI_dec_Di_slave_cnt - Autodecrement an element in the
**			       Di_slave_cnt structure;
**
** Description:
**
** Inputs:
**	Number		Index into Di_slave_cnt array
**
** Outputs:
**	intern_status	Internal error indicating reason for failure.
**
**    Returns:
**        OK
**
**    Exceptions:
**        none
**
** Side Effects:
**        none
**
** History:
**    30-nov-1992 (rmuth)
** 	    Created.
**
*/
STATUS
DI_dec_Di_slave_cnt(
    i4		number,
    STATUS	*intern_status)
{

    STATUS    status;

    do
    {
        status = gen_Psem(&DI_sc_sem);
        if ( status != OK )
        {
            /*
            ** This is very bad as we may have corrupted our internal
            ** DIlru/DIslave structures. But this event can occur
            ** due to a thread being aborted
            */
            --Di_slave_cnt[ number ];
            *intern_status = DI_LRU_GENPSEM_ERR;
            break;
        }

        --Di_slave_cnt[ number ];

        status = gen_Vsem(&DI_sc_sem);
        if ( status != OK )
        {
            Di_fatal_err_occurred = TRUE;
            *intern_status = DI_LRU_GENVSEM_ERR;
            break;
        }

    } while (FALSE);

    return( status );
}
Example #5
0
/******************************************************************************
** Name: MEshow_pages()	- show system's allocated shared memory segments.
**
** Description:
**	This routine is used by clients of the shared memory allocation
**	routines to show what shared memory segments are currently allocated
**	by the system.
**
**	The routine takes a function parameter - 'func' - that will be
**	called once for each existing shared memory segment allocated
**	by Ingres in the current installation.
**
**      The client specified function must have the following call format:
**(
**          STATUS
**          func(arg_list, key, err_code)
**          i4         *arg_list;       Pointer to argument list.
**          char       *key;		Shared segment key.
**          CL_SYS_ERR *err_code;       Pointer to operating system
**                                      error codes (if applicable).
**)
**
**	The following return values from the routine 'func' have special
**	meaning to MEshow_pages:
**
**	    OK (zero)	- If zero is returned from 'func' then MEshow_pages
**			  will continue normally, calling 'func' with the
**			  next shared memory segment.
**	    ENDFILE	- If ENDFILE is returned from 'func' then MEshow_pages
**			  will stop processing and return OK to the caller.
**
**	If 'func' returns any other value, MEshow_pages will stop processing
**	and return that STATUS value to its caller.  Additionally, the system
**	specific 'err_code' value returned by 'func' will be returned to the
**	MEshow_pages caller.
**
** Inputs:
**	func			Function to call with each shared segment.
**	arg_list		Optional pointer to argument list to pass
**				to function.
**
** Outputs:
**	err_code 		System specific error information.
**
**	Returns:
**	    OK
**	    ME_NO_PERM		No permission to show shared memory segment.
**	    ME_BAD_PARAM	Bad function argument.
**	    ME_NO_SHARED	No shared memory in this CL.
**
**	Exceptions:
**	    none
**
** Side Effects:
**	    none
**
******************************************************************************/
STATUS
//MEshow_pages(STATUS		(*func) (PTR, const char *, CL_SYS_ERR *),
MEshow_pages(STATUS		(*func) (),
             PTR        *arg_list,
             CL_SYS_ERR *err_code)
{
	LOCATION        locptr;
	LO_DIR_CONTEXT  lo_dir;
	STATUS          status;
	char            fname[LO_FILENAME_MAX + 1];
	char		dev[LO_DEVNAME_MAX + 1];
	char		path[LO_PATH_MAX + 1];
	char		fprefix[LO_FPREFIX_MAX + 1];
	char		fsuffix[LO_FSUFFIX_MAX + 1];
	char		version[LO_FVERSION_MAX + 1];

	/*
	 * Get location ptr to directory to search for memory segment names.
	 */

# ifdef MCT
	gen_Psem(&NM_loc_sem);
# endif /* MCT */
	if ((status = NMloc(FILES,
	                    PATH,
	                    (char *) NULL,
	                    &locptr)) == OK) {
		LOfaddpath(&locptr,
		           ME_SHMEM_DIR,
		           &locptr);
	} else {
# ifdef MCT
		gen_Vsem(&NM_loc_sem);
# endif /* MCT */
		return (status);
	}
# ifdef MCT
	gen_Vsem(&NM_loc_sem);
# endif /* MCT */

	/*
	 * For each file in the memory location, call the user supplied
	 * function with the filename.  Shared memory keys are built from
	 * these filenames.
	 */

	status = LOwcard(&locptr,
	                 (char *) NULL,
	                 (char *) NULL,
	                 (char *) NULL,
	                 &lo_dir);

	if (status != OK) {
		LOwend(&lo_dir);
		return (ME_NO_SHARED);
	}

	while (status == OK) {
		LOdetail(&locptr, dev, path, fprefix, fsuffix, version);
		(VOID) STpolycat(3, fprefix, ".", fsuffix, fname);
		if (~lo_dir.find_buffer.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
			status = (*func) (arg_list,
			                  fname,
			                  err_code);
			if (status != OK) {
				break;
			}
		}
		status = LOwnext(&lo_dir, &locptr);
	}

	LOwend(&lo_dir);

	if (status == ENDFILE) {
		return (OK);
	}

	return (status);
}
Example #6
0
/*****************************************************************************
** Name: ME_makekey()	- Make WIN32 file for mapping
**                        shared memory from user key.
**
** Description:
**	Create a file to identify a shared memory segment.  The file's inode
**	will be used as a shared memory key.  The file's existence will be
**	used to track shared segments on the system.
**
** Inputs:
**	key			character key identifying shared segment.
**
** Outputs:
**	return value
**
**	Returns:
**	    HANDLE  to opened file, or
**	    -1      file could not be created.
**
**	Exceptions:
**	    none
**
** Side Effects:
**	    File created in installation's memory directory.
**
*****************************************************************************/
HANDLE
ME_makekey(char *user_key)
{
	LOCATION location;
	LOCATION temp_loc;
	char     loc_buf[MAX_LOC + 1];
	char	 *shmemname;

	STATUS   ret_val;
	HANDLE   handle;

	/*
	 * Build location to file in MEMORY directory. Get location of ME
	 * files for shared memory segments.
	 */

# ifdef MCT
	gen_Psem(&NM_loc_sem);
# endif /* MCT */
	ret_val = NMloc(FILES,
	                PATH,
	                (char *) NULL,
	                &temp_loc);
	if (ret_val)
	{
# ifdef MCT
		gen_Vsem(&NM_loc_sem);
# endif /* MCT */
		return (HANDLE) -1;
	}

	LOcopy(&temp_loc,
	       loc_buf,
	       &location);
# ifdef MCT
	gen_Vsem(&NM_loc_sem);
# endif /* MCT */
	LOfaddpath(&location,
	           ME_SHMEM_DIR,
	           &location);
	LOfstfile(user_key,
	          &location);

	/*
	 * Create file to identify the shared segment. This will also allow
	 * MEshow_pages to tell what shared segments have been created.
	 */

	LOtos(&location,
	      &shmemname);
	handle = CreateFile(shmemname,
	                    GENERIC_READ | GENERIC_WRITE,
	                    FILE_SHARE_READ | FILE_SHARE_WRITE,
	                    NULL,
	                    OPEN_ALWAYS,
	                    FILE_ATTRIBUTE_NORMAL,
	                    NULL);

	if (handle == INVALID_HANDLE_VALUE) {
		handle = (HANDLE) -1;
	}

	return (handle);
}
Example #7
0
/*****************************************************************************
** Name: MEshared_free()	- Free shared memory
**
** Description:
**	Free a region of shared memory and return new region for potential
**	futher freeing of the break region.
**
**	If there is attached shared memory in the region being
**	freed then those pages should only be marked free if the whole
**	segment can be detached.
**
**	There is a small table of attached segments which is scanned.
**
** Inputs:
** addr				address of region
**	pages				number of pages to check
**
** Outputs:
**	addr				new address of region
**	pages				new number of pages
**	err_code			CL_ERR_DESC
**
**	Returns:
**	    OK
**	    ME_NOT_ALLOCATED
**
**	Exceptions:
**	    none
**
** Side Effects:
**	    none
**
** History:
**	07-apr-1997 (canor01)
**	    When the shared memory is attached to existing memory
**	    the file handle will be null, so don't try to close it.
**	10-apr-1997 (canor01)
**	    If the address of the memory to be freed does not fall
**	    within the shared memory range, return ME_NOT_ALLOCATED.
**
*****************************************************************************/
STATUS
MEshared_free(PTR         *addr,
              SIZE_TYPE          *pages,
              CL_ERR_DESC *err_code)
{
	STATUS			status = OK;
	register ME_SEG_INFO	*seginf;
	char			*lower, *upper, *last;
	SIZE_TYPE		off, len;
	QUEUE			*next_queue;

	CLEAR_ERR(err_code);

	lower = (char *) *addr;
	upper = lower + ME_MPAGESIZE * *pages;
	last = NULL;

	gen_Psem(&ME_segpool_sem);
	seginf = ME_find_seg(lower, upper, &ME_segpool);
	if ( seginf == NULL )
	{
	    /* memory address was not within shared memory range */
	    gen_Vsem(&ME_segpool_sem);
	    return( ME_NOT_ALLOCATED );
	}
	for ( ;
	     seginf;
	     seginf = ME_find_seg(lower,
	                          upper,
	                          next_queue)) {

		next_queue = &seginf->q;

		if (last && last != seginf->eaddr) {
			status = ME_NOT_ALLOCATED;
			break;
		}

		last = seginf->addr;
		off  = 0;
		len  = seginf->npages;

		if (lower > seginf->addr) {
			off = (lower - seginf->addr) / ME_MPAGESIZE;
			len -= off;
		}

		if (upper < seginf->eaddr) {
			len -= (seginf->eaddr - upper) / ME_MPAGESIZE;
		}

		if (MEalloctst(seginf->allocvec,
		               (i4)off,
		               (i4)len,
		               TRUE)) {
			status = ME_NOT_ALLOCATED;
			break;
		}

		MEclearpg(seginf->allocvec, (i4)off, (i4)len);

		if (!MEalloctst(seginf->allocvec,
		                0,
		                seginf->npages,
		                FALSE)) {
			/* detach segment */
			/*
			 * WARNING::: if the address is NOT the BASE of a
			 * shared memory segment obtained from MapViewOfFile,
			 * we're either gonna fail or puke. Good luck!
			 */

			status = UnmapViewOfFile(seginf->addr);

			if (status == FALSE) {
				status = GetLastError();
				SETCLOS2ERR(err_code, status, ER_mmap);
				gen_Vsem(&ME_segpool_sem);
				return (ME_BAD_PARAM);
			}

			status = CloseHandle(seginf->mem_handle);

			if (status == FALSE) {
				status = GetLastError();
				SETCLOS2ERR(err_code, status, ER_close);
				gen_Vsem(&ME_segpool_sem);
				return (ME_BAD_PARAM);
			}

			/*
			** if just attaching to existing memory,
			** there will just be a memory handle, but
			** the file_handle will be NULL.
			*/
			if ( seginf->file_handle )
			{
			    FlushFileBuffers(seginf->file_handle);
			    status = CloseHandle(seginf->file_handle);
			}

			if (status == FALSE) {
				status = GetLastError();
				SETCLOS2ERR(err_code, status, ER_close);
				gen_Vsem(&ME_segpool_sem);
				return (ME_BAD_PARAM);
			} else {
				status = OK;
			}

			next_queue = ME_rem_seg(seginf);
			*addr = (PTR) NULL;
		}
	}
	gen_Vsem(&ME_segpool_sem);
	return status;
}
Example #8
0
/*{
** Name: TMget_stamp	- Return timestamp.
**
** Description:
**      Return a TM timestamp.
**      Note, this routine is for the sole use of DMF for 
**      auditing and rollforward.
**
** Inputs:
**
** Outputs:
**      time                            Pointer to location to return stamp.
**	Returns:
**	    void
**	Exceptions:
**	    none
**
** Side Effects:
**	    none
**
** History:
**      20-jan-1986 (Derek)
**	    Created.
**      06-jul-1987 (mmm)
**          Initial Jupiter unix cl.
**	28-jul-1988 (daveb)
**	Can't call input parameter "time" because that confilcts with the
**		"time" system call you need on System V.
**	1-sep-89 (daveb)
**		Enhance the uniqueness of the stamp by salting in the low
**		8 bits of the pid.
**      21-jun-93 (mikem)
**	    Only call getpid() once per process.
**	20-apr-94 (mikem)
**	    Added use of 2 new #defines (xCL_GETTIMEOFDAY_TIMEONLY and
**	    xCL_GETTIMEOFDAY_TIME_AND_TZ) in TMget_stamp() to describe 2 
**	    versions of gettimeofday() available.  
**      29-Aug-2002 (hanal04) Bug 108609 INGSRV 1869.
**          Explicitly set _daylight, _timezone and _tzname[0] in the
**          DLL's global space. tzset() failed to pickup these values
**          from the Date & Time application when TZ is not set so
**          we must derrive them from GetTimezoneInformation() values.
*/
void
TMget_stamp(
TM_STAMP	*stamp)
{
    static int	pid = 0;
    static TM_STAMP   last_stamp = { 0, 0 };

    time_t secs;
    SYSTEMTIME stime;
    TIME_ZONE_INFORMATION tz;
    static bool           tz_init = TRUE;

    if(tz_init)
    {
        tz_init = FALSE;

        GetTimeZoneInformation( &tz );
 
        /* Now setup the values tzset() should set but doesn't */
        if(tz.DaylightBias)
            _daylight = 1;
        else
            _daylight = 0;

        _timezone = tz.Bias * 60;

        WideCharToMultiByte( CP_OEMCP, 0, tz.StandardName, -1, _tzname[0], 
                         sizeof(_tzname[0]), NULL, NULL);
    }

    secs = time(NULL);
    GetSystemTime( &stime );

    stamp->tms_sec = (i4)secs;
    stamp->tms_usec = stime.wMilliseconds * 1000;

    /* To enhance the uniqueness of the returned value as a stamp,
    ** salt in the low 8 bits worth of the pid (daveb) 
    */
    gen_Psem(&CL_misc_sem);
    if (!pid)
    {
	pid = getpid();

        /* B63625 (canor01)
        ** Since the low-order bits of the pid could potentially
        ** affect the above calculations, as a medium-term fix
        ** (suggested by sweeney) left shift the pid by two bits
        ** before or'ing it in.  Really, though, we need two 
        ** functions--one for unique stamp and one for time.
        */
    	pid <<= 2;
    }


    /* B63625: To further enhance the uniqueness of the returned value
    ** as a stamp in the case of *very* fast machines, make sure 
    ** returns on consecutive calls are different. (canor01) 
    */
    if ( stamp->tms_sec == last_stamp.tms_sec &&
	 stamp->tms_usec <= last_stamp.tms_usec )
        stamp->tms_usec = ++last_stamp.tms_usec;
    last_stamp.tms_sec  = stamp->tms_sec;
    last_stamp.tms_usec = stamp->tms_usec;
    gen_Vsem(&CL_misc_sem);

    stamp->tms_usec |= (pid & 0xff);
}