This is Unofficial EPICS BASE Doxygen Site
camsgtask.c
Go to the documentation of this file.
1 /*************************************************************************\
2 * Copyright (c) 2002 The University of Chicago, as Operator of Argonne
3 * National Laboratory.
4 * Copyright (c) 2002 The Regents of the University of California, as
5 * Operator of Los Alamos National Laboratory.
6 * EPICS BASE Versions 3.13.7
7 * and higher are distributed subject to a Software License Agreement found
8 * in file LICENSE that is included with this distribution.
9 \*************************************************************************/
10 /*
11  * Author: Jeffrey O. Hill
12  * hill@luke.lanl.gov
13  * (505) 665 1831
14  * Date: 6-88
15  */
16 
17 
18 #include <stddef.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <errno.h>
22 
23 #include "dbDefs.h"
24 #include "epicsStdio.h"
25 #include "epicsTime.h"
26 #include "errlog.h"
27 #include "osiSock.h"
28 #include "taskwd.h"
29 
30 #include "caerr.h"
31 
32 #define epicsExportSharedSymbols
33 #include "db_access.h"
34 #include "rsrv.h"
35 #include "server.h"
36 
37 /*
38  * camsgtask()
39  *
40  * CA server TCP client task (one spawned for each client)
41  */
42 void camsgtask ( void *pParm )
43 {
44  struct client *client = (struct client *) pParm;
45 
46  casAttachThreadToClient ( client );
47 
48  while (castcp_ctl == ctlRun && !client->disconnect) {
49  osiSockIoctl_t check_nchars;
50  long nchars;
51  int status;
52 
53  /*
54  * allow message to batch up if more are comming
55  */
56  status = socket_ioctl (client->sock, FIONREAD, &check_nchars);
57  if (status < 0) {
58  char sockErrBuf[64];
59 
61  sockErrBuf, sizeof ( sockErrBuf ) );
62  errlogPrintf("CAS: FIONREAD error: %s\n",
63  sockErrBuf);
64  cas_send_bs_msg(client, TRUE);
65  }
66  else if (check_nchars == 0){
67  cas_send_bs_msg(client, TRUE);
68  }
69 
70  client->recv.stk = 0;
71  assert ( client->recv.maxstk >= client->recv.cnt );
72  nchars = recv ( client->sock, &client->recv.buf[client->recv.cnt],
73  (int) ( client->recv.maxstk - client->recv.cnt ), 0 );
74  if ( nchars == 0 ){
75  if ( CASDEBUG > 0 ) {
76  /* convert to u long so that %lu works on both 32 and 64 bit archs */
77  unsigned long cnt = sizeof ( client->recv.buf ) - client->recv.cnt;
78  errlogPrintf ( "CAS: nill message disconnect ( %lu bytes request )\n",
79  cnt );
80  }
81  break;
82  }
83  else if ( nchars < 0 ) {
84  int anerrno = SOCKERRNO;
85 
86  if ( anerrno == SOCK_EINTR ) {
87  continue;
88  }
89 
90  if ( anerrno == SOCK_ENOBUFS ) {
91  errlogPrintf (
92  "CAS: Out of network buffers, retring receive in 15 seconds\n" );
93  epicsThreadSleep ( 15.0 );
94  continue;
95  }
96 
97  /*
98  * normal conn lost conditions
99  */
100  if ( ( anerrno != SOCK_ECONNABORTED &&
101  anerrno != SOCK_ECONNRESET &&
102  anerrno != SOCK_ETIMEDOUT ) ||
103  CASDEBUG > 2 ) {
104  char sockErrBuf[64];
105 
107  sockErrBuf, sizeof ( sockErrBuf ), anerrno);
108  errlogPrintf ( "CAS: Client disconnected - %s\n",
109  sockErrBuf );
110  }
111  break;
112  }
113 
115  client->recv.cnt += ( unsigned ) nchars;
116 
117  status = camessage ( client );
118  if (status == 0) {
119  /*
120  * if there is a partial message
121  * align it with the start of the buffer
122  */
123  if (client->recv.cnt > client->recv.stk) {
124  unsigned bytes_left;
125 
126  bytes_left = client->recv.cnt - client->recv.stk;
127 
128  /*
129  * overlapping regions handled
130  * properly by memmove
131  */
132  memmove (client->recv.buf,
133  &client->recv.buf[client->recv.stk], bytes_left);
134  client->recv.cnt = bytes_left;
135  }
136  else {
137  client->recv.cnt = 0ul;
138  }
139  }
140  else {
141  char buf[64];
142 
143  /* flush any queued messages before shutdown */
144  cas_send_bs_msg(client, 1);
145 
146  client->recv.cnt = 0ul;
147 
148  /*
149  * disconnect when there are severe message errors
150  */
151  ipAddrToDottedIP (&client->addr, buf, sizeof(buf));
152  epicsPrintf ("CAS: forcing disconnect from %s\n", buf);
153  break;
154  }
155  }
156 
157  LOCK_CLIENTQ;
158  ellDelete ( &clientQ, &client->node );
160 
161  destroy_tcp_client ( client );
162 }
163 
164 
165 int casClientInitiatingCurrentThread ( char * pBuf, size_t bufSize )
166 {
167  struct client * pClient = ( struct client * )
169 
170  if ( ! pClient )
171  return RSRV_ERROR;
172 
173  if ( pBuf && bufSize ) {
174  epicsSnprintf(pBuf, bufSize, "ca:%s@%s",
175  pClient->pUserName, pClient->pHostName);
176  }
177  return RSRV_OK;
178 }
179 
GLBLTYPE int CASDEBUG
Definition: server.h:190
void casAttachThreadToClient(struct client *pClient)
#define SOCK_ECONNABORTED
Definition: osdSock.h:59
struct message_buffer recv
Definition: server.h:81
#define assert(exp)
Declare that a condition should be true.
Definition: epicsAssert.h:70
unsigned cnt
Definition: server.h:70
void destroy_tcp_client(struct client *client)
pvd::Status status
unsigned maxstk
Definition: server.h:68
char * pUserName
Definition: server.h:93
#define SOCK_ENOBUFS
Definition: osdSock.h:52
LIBCOM_API void *epicsStdCall epicsThreadPrivateGet(epicsThreadPrivateId)
Definition: osdThread.c:973
#define SOCK_ETIMEDOUT
Definition: osdSock.h:54
epicsThreadPrivateId rsrvCurrentClient
Definition: caservertask.c:50
#define LOCK_CLIENTQ
Definition: server.h:223
SOCKET sock
Definition: server.h:96
unsigned stk
Definition: server.h:67
Miscellaneous macro definitions.
struct sockaddr_in addr
Definition: server.h:89
void epicsSocketConvertErrnoToString(char *pBuf, unsigned bufSize)
#define socket_ioctl(A, B, C)
Definition: osdSock.h:34
char * pHostName
Definition: server.h:94
#define SOCK_ECONNRESET
Definition: osdSock.h:53
char disconnect
Definition: server.h:103
int osiSockIoctl_t
Definition: osdSock.h:35
Definition: server.h:169
Definition: server.h:76
epicsTimeStamp time_at_last_recv
Definition: server.h:91
int epicsStdCall epicsTimeGetCurrent(epicsTimeStamp *pDest)
Get current time into *pDest.
#define RSRV_OK
Definition: rsrv.h:23
#define epicsPrintf
Definition: errlog.h:51
char * buf
Definition: server.h:65
int camessage(struct client *client)
Definition: camessage.c:2391
int errlogPrintf(const char *pFormat,...)
Definition: errlog.c:105
GLBLTYPE enum ctl castcp_ctl
Definition: server.h:214
#define SOCKERRNO
Definition: osdSock.h:33
#define RSRV_ERROR
Definition: rsrv.h:24
void camsgtask(void *pParm)
Definition: camsgtask.c:42
#define SOCK_EINTR
Definition: osdSock.h:64
#define TRUE
Definition: dbDefs.h:27
LIBCOM_API void epicsStdCall epicsThreadSleep(double seconds)
Block the calling thread for at least the specified time.
Definition: osdThread.c:790
ELLNODE node
Definition: server.h:77
#define UNLOCK_CLIENTQ
Definition: server.h:224
EPICS time-stamps (epicsTimeStamp), epicsTime C++ class and C functions for handling wall-clock times...
void ellDelete(ELLLIST *pList, ELLNODE *pNode)
Deletes a node from a list.
Definition: ellLib.c:75
void cas_send_bs_msg(struct client *pclient, int lock_needed)
Definition: caserverio.c:44
void epicsSocketConvertErrorToString(char *pBuf, unsigned bufSize, int theSockError)
int casClientInitiatingCurrentThread(char *pBuf, size_t bufSize)
Definition: camsgtask.c:165
LIBCOM_API int epicsStdCall epicsSnprintf(char *str, size_t size, const char *format,...) EPICS_PRINTF_STYLE(3
unsigned epicsStdCall ipAddrToDottedIP(const struct sockaddr_in *paddr, char *pBuf, unsigned bufSize)
Definition: osiSock.c:144