Example #1
0
// extern "C"
int epicsShareAPI ca_build_and_connect ( const char *name_str, chtype get_type,
            arrayElementCount get_count, chid * chan, void *pvalue, 
            caCh *conn_func, void *puser )
{
    if ( get_type != TYPENOTCONN && pvalue != 0 && get_count != 0 ) {
        return ECA_ANACHRONISM;
    }

    return ca_search_and_connect ( name_str, chan, conn_func, puser );
}
Example #2
0
/*
 * create a channel entry, and lookup all details
 */
Channel *
build_PV(char * name)
{
	Channel *chan;
	int st;

	chan = (Channel *) calloc( 1, sizeof *chan);
	if( !chan)
		return 0;
	chan->chan_name = strdup(name);
	chan->initData = 1;
	chan->createData = 1;
	chan->monitor = 1;
	chan->outstanding = 1;
	st = ca_search_and_connect(name, &(chan->chan_id), connect_callback, chan);
	DEBUGP printf("ca_search_and_connect = %d\n", st);
	ca_flush_io();
	return chan;
}
Example #3
0
Channel *
init_PV(char *name, chtype chan_type, void *dataptr, int size)
{
    Channel *chan;
    int st;
    
    DEBUGP printf("init_PV(%s, ...)\n", name);
    chan = (Channel *) calloc( 1, sizeof (Channel));
    if( !chan)
	return 0;
    DEBUGP printf("Channel Allocated %p\n", chan);
    chan->chan_name = strdup(name);
    chan->chan_type = chan_type;
    chan->dataval = dataptr;
    chan->maxelement = size;
    chan->outstanding = 1;
    
    st = ca_search_and_connect(name, &(chan->chan_id), connect_callback, chan);
    DEBUGP printf("ca_search_and_connect = %d\n", st);
    ca_flush_io();
    return chan;
}
Example #4
0
int main(int argc, char** argv)
{
	fd_set rfds;
	int tot;
	struct timeval tv;

	if(argc!=3)
	{
		fprintf(stderr,"Usage: %s PV_to_monitor script_to_run\n\n",argv[0]);
		fprintf(stderr,"This program monitored PV PV_to_monitor and\n");
		fprintf(stderr,"runs and executes script_to_run, which can be\n");
		fprintf(stderr,"any program or executable script.\n");
		fprintf(stderr,"The script or program gets invoked with the first\n");
		fprintf(stderr,"argument as the PV name and the second argument\n");
		fprintf(stderr,"as the value of the PV\n");
		fprintf(stderr,"The program or shell script script_to_run is\n");
		fprintf(stderr,"run as a separate child process of this program\n");
		fprintf(stderr,"This means that your script or program will not\n");
		fprintf(stderr,"stop this process from running, if fact your\n");
		fprintf(stderr,"script or program can be invoked many times if\n");
		fprintf(stderr,"the value of the PV is changing rapidly and\n");
		fprintf(stderr,"several instances of your program could be running\n");
		fprintf(stderr,"simultaneously.\n");
		return -1;
	}

	strcpy(pv_name,argv[1]);
	script_name=argv[2];
	pv_value[0]='\0';

	if(access(script_name,X_OK)<0)
	{
		fprintf(stderr,"Script %s not found or not executable\n",script_name);
		return -1;
	}

	signal(SIGINT,sig_func);
	signal(SIGQUIT,sig_func);
	signal(SIGTERM,sig_func);
	signal(SIGHUP,sig_func);
	signal(SIGCHLD,sig_chld);

	FD_ZERO(&all_fds);

	SEVCHK(ca_task_initialize(),"task initialize");
	SEVCHK(ca_add_fd_registration(fdCB,&all_fds),"add fd registration");
	SEVCHK(ca_add_exception_event(exCB,NULL),"add exception event");

	SEVCHK(ca_search_and_connect(pv_name,&id,conCB,NULL),
		"search and connect");
	SEVCHK(ca_replace_access_rights_event(id,accCB),
		"replace access rights event");

	/* SEVCHK(ca_add_event(DBR_TIME_STRING,data.id,evCB,&data,&data.event),
		"add event"); */

	ca_pend_event(REALLY_SMALL);

	/* fprintf(stderr,"Monitoring <%s>\n",pv_name); */

	while(do_not_exit)
	{
		rfds=all_fds;
		tv.tv_sec=1;
		tv.tv_usec=0; /*200000*/;

		switch(tot=select(FD_SETSIZE,&rfds,NULL,NULL,&tv))
		{
		/*
		case -1:
			perror("select error - bad");
			break;
		*/
		case 0:
			ca_pend_event(REALLY_SMALL);
			break;
		default:
			/* fprintf(stderr,"select data ready\n"); */
			ca_pend_event(REALLY_SMALL);
			break;
		}
	}

	fprintf(stderr,"PV monitor program is exiting!\n");
	ca_task_exit();
	return 0;
}
/* Find an unconnected PV and attempt to connect to it.  That should
 * restart the searches for all other unresolved PVs. */
void retryConnections(void)
{
    int i,j;
    const char *pvname=NULL;
    chid retryChid;
    int status;

#if DEBUG_RETRY
    print("retryConnections:\n");
    print(" freeListSize=%d freeListCount=%d\n",
      caTask.freeListSize,caTask.freeListCount);
    print(" pageSize=%d pageCount=%d\n",
      caTask.pageSize,caTask.pageCount);
    print(" nextpage=%d nextFree=%d\n",
      caTask.nextPage,caTask.nextFree);
    print(" channelCount=%d channelConnected=%d\n",
      caTask.channelCount,caTask.channelConnected);
    if(caTask.nextPage != caTask.pageCount-1) {
	print(" caTask.nextPage != caTask.pageCount-1\n");
    }
#else
  /* Check if all channels are connected */
    if(caTask.channelCount == caTask.channelConnected) {
	medmPostMsg(1,"retryConnections: All channels are connected\n");
	XBell(display, 50);
	return;
    }
#endif

  /* Find an unconnected PV */
    for(i=0; i < caTask.pageCount; i++) {
	int jmax=(i == caTask.nextPage)?caTask.nextFree:CA_PAGE_SIZE;
	for(j=0; j < jmax; j++) {
	    Channel *pCh=&caTask.pages[i][j];
	    if(pCh->chid && ca_state(pCh->chid) != cs_conn) {
		pvname=ca_name(pCh->chid);
		break;
	    }
	}
	if(pvname) break;
    }
#if DEBUG_RETRY
    print(" Found %s\n",pvname?pvname:"Not found");
    if(!pvname) return;
#else
    if(!pvname) {
	medmPostMsg(1,"retryConnections: Failed to find unconnected PV\n");
	return;
    }
#endif

  /* Search */
    status=ca_search_and_connect(pvname,&retryChid,NULL,NULL);
    if(status != ECA_NORMAL) {
	medmPostMsg(1,"retryConnections: ca_search failed for %s: %s\n",
	  pvname, ca_message(status));
    }

  /* Wait.  The searches will only continue for this time.  Keep the
   * time short as the interface is frozen, and most of the searches
   * occur at the start of the sequence.  Testing indicated:
   *
   * RETRY_TIMEOUT Searches
   *      30          15
   *       5          10
   *       3           9
   *       2           9
   *       1           8
   *
   * but this may vary owing to tuning and may change with new releases.
   */
    ca_pend_io(RETRY_TIMEOUT);

  /* Clear the channel */
    status = ca_clear_channel(retryChid);
    if(status != ECA_NORMAL) {
	medmPostMsg(1,"retryConnections: ca_clear_channel failed for %s: %s\n",
	  pvname, ca_message(status));
    }
}
static int caAdd(char *name, Record *pr)
{
    Channel *pCh;
    int status;

    if((caTask.freeListCount < 1) && (caTask.nextFree >= CA_PAGE_SIZE)) {
      /* if not enough pages, increase number of pages */
	if(caTask.pageCount >= caTask.pageSize) {
	    caTask.pageSize += CA_PAGE_COUNT;
#if defined(__cplusplus) && !defined(__GNUG__)
	    caTask.pages = (Channel **)realloc((malloc_t)caTask.pages,
	      sizeof(Channel *)*caTask.pageSize);
#else
	    caTask.pages = (Channel **)realloc(caTask.pages,
	      sizeof(Channel *)*caTask.pageSize);
#endif
	    if(caTask.pages == NULL) {
		medmPostMsg(1,"caAdd: Memory allocation error\n");
		return -1;
	    }
	}
      /* add one more page */
	caTask.pages[caTask.pageCount] = (Channel *)malloc(sizeof(Channel) *
	  CA_PAGE_SIZE);
	if(caTask.pages[caTask.pageCount] == NULL) {
	    medmPostMsg(1,"caAdd: Memory allocation error\n");
	    return -1;
	}
	caTask.pageCount++;
	caTask.nextPage++;
	caTask.nextFree=0;
    }
    if(caTask.nextFree < CA_PAGE_SIZE) {
	pCh = &((caTask.pages[caTask.nextPage])[caTask.nextFree]);
	pCh->caId = caTask.nextPage * CA_PAGE_SIZE + caTask.nextFree;
	caTask.nextFree++;
    } else {
	int index;
	caTask.freeListCount--;
	index = caTask.freeList[caTask.freeListCount];
	pCh = &((caTask.pages[index/CA_PAGE_SIZE])[index % CA_PAGE_SIZE]);
	pCh->caId = index;
    }

    pCh->data = NULL;
    pCh->chid = NULL;
    pCh->evid = NULL;
    pCh->size = 0;
    pCh->pr = pr;
    pCh->previouslyConnected = False;

  /* Do the search */
    status = ca_search_and_connect(name, &(pCh->chid), medmConnectEventCb,
      pCh);
    if(status != ECA_NORMAL) {
	medmPostMsg(1,"caAdd: ca_search_and_connect failed: %s\n",
	  ca_message(status));
    } else {
      /* Cast to avoid warning from READONLY */
	pCh->pr->name = (char *)ca_name(pCh->chid);
    }
    caTask.channelCount++;
#if DEBUG_ADD
    print("caAdd: %3d name=%s\n",
      caTask.channelCount, name);
#endif
    return pCh->caId;
}