99 lines
2.9 KiB
C
99 lines
2.9 KiB
C
|
/****************************************************************
|
||
|
* *
|
||
|
* Copyright 2008 Fidelity Information Services, Inc *
|
||
|
* *
|
||
|
* This source code contains the intellectual property *
|
||
|
* of its copyright holder(s), and is made available *
|
||
|
* under a license. If you do not know the terms of *
|
||
|
* the license, please stop and do not read further. *
|
||
|
* *
|
||
|
****************************************************************/
|
||
|
|
||
|
/* gtm_relqueopi - C-callable relative queue interlocked routines
|
||
|
*
|
||
|
* These routines perform interlocked operations on doubly-linked
|
||
|
* relative queues. They are designed to emulate the VAX machine
|
||
|
* instructions (and corresponding VAX C library routines) after
|
||
|
* which they are named.
|
||
|
*
|
||
|
* insqhi - insert entry into queue at head, interlocked
|
||
|
* insqti - insert entry into queue at tail, interlocked
|
||
|
* remqhi - remove entry from queue at head, interlocked
|
||
|
* remqti - remove entry from queue at tail, interlocked
|
||
|
*/
|
||
|
|
||
|
#include "mdef.h"
|
||
|
|
||
|
#include "relqueopi.h"
|
||
|
|
||
|
#ifdef DEBUG
|
||
|
|
||
|
/* An element that is not present in the queue should have its fl,bl fields zero.
|
||
|
* An element that is present in the queue should have its fl,bl fields non-zero.
|
||
|
* Ensure/Check this property for all queue operations.
|
||
|
* This will help catch a case when an element that is already present in the queue is re-added into the same queue.
|
||
|
* Such operations will cause queue corruption and since the queue is in shared memory (given that the interlocked
|
||
|
* queue operations are being done), could cause shared memory corruption and database damage (D9H03-002644).
|
||
|
*/
|
||
|
int gtm_insqhi(que_ent_ptr_t new, que_head_ptr_t base)
|
||
|
{
|
||
|
int4 status;
|
||
|
|
||
|
assert(0 == new->fl);
|
||
|
assert(0 == new->bl);
|
||
|
status = SYS_INSQHI(new, base);
|
||
|
/* We cannot assert that new->fl and new->bl are non-zero at this point since they
|
||
|
* could be concurrently removed from the queue right after we inserted it above.
|
||
|
*/
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
int gtm_insqti(que_ent_ptr_t new, que_head_ptr_t base)
|
||
|
{
|
||
|
int4 status;
|
||
|
|
||
|
assert(0 == new->fl);
|
||
|
assert(0 == new->bl);
|
||
|
status = SYS_INSQTI(new, base);
|
||
|
/* We cannot assert that new->fl and new->bl are non-zero at this point since they
|
||
|
* could be concurrently removed from the queue right after we inserted it above.
|
||
|
*/
|
||
|
return status;
|
||
|
}
|
||
|
|
||
|
void_ptr_t gtm_remqhi(que_head_ptr_t base)
|
||
|
{
|
||
|
que_ent_ptr_t ret;
|
||
|
|
||
|
ret = SYS_REMQHI(base);
|
||
|
if (NULL != ret)
|
||
|
{
|
||
|
# ifndef UNIX /* in Unix, relqueopi.c already does the rest of fl,bl to 0 just before releasing the swap lock */
|
||
|
ret->fl = 0;
|
||
|
ret->bl = 0;
|
||
|
# endif
|
||
|
assert(0 == ret->fl);
|
||
|
assert(0 == ret->bl);
|
||
|
}
|
||
|
return (void_ptr_t)ret;
|
||
|
}
|
||
|
|
||
|
void_ptr_t gtm_remqti(que_head_ptr_t base)
|
||
|
{
|
||
|
que_ent_ptr_t ret;
|
||
|
|
||
|
ret = SYS_REMQTI(base);
|
||
|
if (NULL != ret)
|
||
|
{
|
||
|
# ifndef UNIX /* in Unix, relqueopi.c already does the rest of fl,bl to 0 just before releasing the swap lock */
|
||
|
ret->fl = 0;
|
||
|
ret->bl = 0;
|
||
|
# endif
|
||
|
assert(0 == ret->fl);
|
||
|
assert(0 == ret->bl);
|
||
|
}
|
||
|
return (void_ptr_t)ret;
|
||
|
}
|
||
|
|
||
|
#endif
|