Files
epics-base/modules/ca/src/client/syncgrp.cpp
Dirk Zimoch 90a727c901 Fix spelling errors
Most errors found with:

codespell -L cach,thst,odly,aslo,parm,parms,inpu,ges,prset,pevent,ptd,pring,valu,noo,noe,ned,inout,ro,siz,froms,nd,fo,singl,sart,multy,tthe,allong,ment,inate,nodel,tring,alse,ture,thi,wille,numer

Some more manually found (its -> it's)

c++20: Do not use apostrophe (e.g. can't) in unquoted #error message
2025-12-01 19:00:04 -08:00

363 lines
9.7 KiB
C++

/*************************************************************************\
* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
* National Laboratory.
* Copyright (c) 2002 The Regents of the University of California, as
* Operator of Los Alamos National Laboratory.
* SPDX-License-Identifier: EPICS
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/*
* Author: Jeffrey O. Hill
* hill@luke.lanl.gov
* (505) 665 1831
*/
#define epicsAssertAuthor "Jeff Hill johill@lanl.gov"
#include "iocinf.h"
#include "oldAccess.h"
#include "syncGroup.h"
/*
* ca_sg_create()
*/
extern "C" int epicsStdCall ca_sg_create ( CA_SYNC_GID * pgid )
{
ca_client_context * pcac;
int caStatus;
CASG * pcasg;
caStatus = fetchClientContext ( &pcac );
if ( caStatus != ECA_NORMAL ) {
return caStatus;
}
try {
epicsGuard < epicsMutex > guard ( pcac->mutexRef() );
pcasg = new ( pcac->casgFreeList ) CASG ( guard, *pcac );
*pgid = pcasg->getId ();
return ECA_NORMAL;
}
catch ( std::bad_alloc & ) {
return ECA_ALLOCMEM;
}
catch ( ... ) {
return ECA_INTERNAL;
}
}
int ca_sync_group_destroy ( CallbackGuard & cbGuard, epicsGuard < epicsMutex > & guard,
ca_client_context & cac, const CA_SYNC_GID gid )
{
int caStatus;
CASG * pcasg = cac.lookupCASG ( guard, gid );
if ( pcasg ) {
pcasg->destructor ( cbGuard, guard );
cac.casgFreeList.release ( pcasg );
caStatus = ECA_NORMAL;
}
else {
caStatus = ECA_BADSYNCGRP;
}
return caStatus;
}
/*
* ca_sg_delete()
*/
extern "C" int epicsStdCall ca_sg_delete ( const CA_SYNC_GID gid )
{
ca_client_context * pcac;
int caStatus = fetchClientContext ( & pcac );
if ( caStatus == ECA_NORMAL ) {
if ( pcac->pCallbackGuard.get() &&
pcac->createdByThread == epicsThreadGetIdSelf () ) {
epicsGuard < epicsMutex > guard ( pcac->mutex );
caStatus = ca_sync_group_destroy ( *pcac->pCallbackGuard.get(),
guard, *pcac, gid );
}
else {
//
// we will definitely stall out here if all of the
// following are true
//
// o user creates non-preemptive mode client library context
// o user doesn't periodically call a ca function
// o user calls this function from an auxiliary thread
//
CallbackGuard cbGuard ( pcac->cbMutex );
epicsGuard < epicsMutex > guard ( pcac->mutex );
caStatus = ca_sync_group_destroy ( cbGuard, guard, *pcac, gid );
}
}
return caStatus;
}
void sync_group_reset ( ca_client_context & client, CASG & sg )
{
if ( client.pCallbackGuard.get() &&
client.createdByThread == epicsThreadGetIdSelf () ) {
epicsGuard < epicsMutex > guard ( client.mutex );
sg.reset ( *client.pCallbackGuard.get(), guard );
}
else {
//
// we will definitely stall out here if all of the
// following are true
//
// o user creates non-preemptive mode client library context
// o user doesn't periodically call a ca function
// o user calls this function from an auxiliary thread
//
CallbackGuard cbGuard ( client.cbMutex );
epicsGuard < epicsMutex > guard ( client.mutex );
sg.reset ( cbGuard, guard );
}
}
//
// ca_sg_block ()
//
// !!!! This routine is only visible in the old interface - or in a new ST interface.
// !!!! In the old interface we restrict thread attach so that calls from threads
// !!!! other than the initializing thread are not allowed if preemptive callback
// !!!! is disabled. This prevents the preemptive callback lock from being released
// !!!! by other threads than the one that locked it.
//
extern "C" int epicsStdCall ca_sg_block (
const CA_SYNC_GID gid, ca_real timeout )
{
ca_client_context *pcac;
int status = fetchClientContext ( &pcac );
if ( status == ECA_NORMAL ) {
CASG * pcasg;
{
epicsGuard < epicsMutex > guard ( pcac->mutex );
pcasg = pcac->lookupCASG ( guard, gid );
if ( pcasg ) {
status = pcasg->block (
pcac->pCallbackGuard.get (), guard, timeout );
}
else {
status = ECA_BADSYNCGRP;
}
}
if ( pcasg ) {
sync_group_reset ( *pcac, *pcasg );
}
}
return status;
}
/*
* ca_sg_reset
*/
extern "C" int epicsStdCall ca_sg_reset ( const CA_SYNC_GID gid )
{
ca_client_context *pcac;
int caStatus = fetchClientContext (&pcac);
if ( caStatus == ECA_NORMAL ) {
CASG * pcasg;
{
epicsGuard < epicsMutex > guard ( pcac->mutex );
pcasg = pcac->lookupCASG ( guard, gid );
}
if ( pcasg ) {
sync_group_reset ( *pcac, *pcasg );
caStatus = ECA_NORMAL;
}
else {
caStatus = ECA_BADSYNCGRP;
}
}
return caStatus;
}
/*
* ca_sg_stat
*/
extern "C" int epicsStdCall ca_sg_stat ( const CA_SYNC_GID gid )
{
ca_client_context * pcac;
int caStatus = fetchClientContext ( &pcac );
if ( caStatus != ECA_NORMAL ) {
return caStatus;
}
epicsGuard < epicsMutex > guard ( pcac->mutexRef() );
CASG * pcasg = pcac->lookupCASG ( guard, gid );
if ( ! pcasg ) {
::printf ( "Bad Sync Group Id\n");
return ECA_BADSYNCGRP;
}
pcasg->show ( guard, 1000u );
return ECA_NORMAL;
}
/*
* ca_sg_test
*/
extern "C" int epicsStdCall ca_sg_test ( const CA_SYNC_GID gid )
{
ca_client_context * pcac;
int caStatus = fetchClientContext ( &pcac );
if ( caStatus == ECA_NORMAL ) {
epicsGuard < epicsMutex > guard ( pcac->mutexRef() );
CASG * pcasg = pcac->lookupCASG ( guard, gid );
if ( pcasg ) {
bool isComplete;
if ( pcac->pCallbackGuard.get() &&
pcac->createdByThread == epicsThreadGetIdSelf () ) {
epicsGuard < epicsMutex > guard ( pcac->mutex );
isComplete = pcasg->ioComplete ( *pcac->pCallbackGuard.get(), guard );
}
else {
//
// we will definitely stall out here if all of the
// following are true
//
// o user creates non-preemptive mode client library context
// o user doesn't periodically call a ca function
// o user calls this function from an auxiliary thread
//
CallbackGuard cbGuard ( pcac->cbMutex );
epicsGuard < epicsMutex > guard ( pcac->mutex );
isComplete = pcasg->ioComplete ( cbGuard, guard );
}
if ( isComplete ) {
caStatus = ECA_IODONE;
}
else{
caStatus = ECA_IOINPROGRESS;
}
}
else {
caStatus = ECA_BADSYNCGRP;
}
}
return caStatus;
}
/*
* ca_sg_array_put()
*/
extern "C" int epicsStdCall ca_sg_array_put ( const CA_SYNC_GID gid, chtype type,
arrayElementCount count, chid pChan, const void *pValue )
{
ca_client_context *pcac;
int caStatus = fetchClientContext ( &pcac );
if ( caStatus != ECA_NORMAL ) {
return caStatus;
}
epicsGuard < epicsMutex > guard ( pcac->mutexRef() );
CASG * const pcasg = pcac->lookupCASG ( guard, gid );
if ( ! pcasg ) {
return ECA_BADSYNCGRP;
}
try {
pcasg->put ( guard, pChan, type,
static_cast < unsigned > ( count ), pValue );
return ECA_NORMAL;
}
catch ( cacChannel::badString & )
{
return ECA_BADSTR;
}
catch ( cacChannel::badType & )
{
return ECA_BADTYPE;
}
catch ( cacChannel::outOfBounds & )
{
return ECA_BADCOUNT;
}
catch ( cacChannel::noWriteAccess & )
{
return ECA_NOWTACCESS;
}
catch ( cacChannel::notConnected & )
{
return ECA_DISCONN;
}
catch ( cacChannel::unsupportedByService & )
{
return ECA_UNAVAILINSERV;
}
catch ( cacChannel::requestTimedOut & )
{
return ECA_TIMEOUT;
}
catch ( std::bad_alloc & )
{
return ECA_ALLOCMEM;
}
catch ( ... )
{
return ECA_INTERNAL;
}
}
/*
* ca_sg_array_get()
*/
extern "C" int epicsStdCall ca_sg_array_get ( const CA_SYNC_GID gid, chtype type,
arrayElementCount count, chid pChan, void *pValue )
{
ca_client_context *pcac;
int caStatus = fetchClientContext ( &pcac );
if ( caStatus != ECA_NORMAL ) {
return caStatus;
}
epicsGuard < epicsMutex > guard ( pcac->mutexRef() );
CASG * const pcasg = pcac->lookupCASG ( guard, gid );
if ( ! pcasg ) {
return ECA_BADSYNCGRP;
}
try {
pcasg->get ( guard, pChan, type,
static_cast < unsigned > ( count ), pValue );
return ECA_NORMAL;
}
catch ( cacChannel::badString & )
{
return ECA_BADSTR;
}
catch ( cacChannel::badType & )
{
return ECA_BADTYPE;
}
catch ( cacChannel::outOfBounds & )
{
return ECA_BADCOUNT;
}
catch ( cacChannel::noReadAccess & )
{
return ECA_NORDACCESS;
}
catch ( cacChannel::notConnected & )
{
return ECA_DISCONN;
}
catch ( cacChannel::unsupportedByService & )
{
return ECA_UNAVAILINSERV;
}
catch ( std::bad_alloc & )
{
return ECA_ALLOCMEM;
}
catch ( ... )
{
return ECA_INTERNAL;
}
}