disconnect callback

This commit is contained in:
zimoch
2007-11-30 15:23:13 +00:00
parent 161f3c7d3c
commit ed8b3aded1
5 changed files with 73 additions and 43 deletions

View File

@ -186,7 +186,7 @@ class AsynDriverInterface : StreamBusInterface
bool supportsEvent();
bool supportsAsyncRead();
bool connectRequest(unsigned long connecttimeout_ms);
bool disconnect();
bool disconnectRequest();
void finish();
#ifdef EPICS_3_14
@ -462,11 +462,6 @@ lockRequest(unsigned long lockTimeout_ms)
clientName(), lockTimeout_ms);
asynStatus status;
lockTimeout = lockTimeout_ms ? lockTimeout_ms*0.001 : -1.0;
if (!lockTimeout_ms)
{
if (!connectToAsynPort()) return false;
}
ioAction = Lock;
status = pasynManager->queueRequest(pasynUser, priority(),
lockTimeout);
@ -497,6 +492,8 @@ connectToAsynPort()
clientName(), pasynUser->errorMessage);
return false;
}
debug("AsynDriverInterface::connectToAsynPort(%s) is %s connected\n",
clientName(), connected ? "already" : "not yet");
if (!connected)
{
status = pasynCommon->connect(pvtCommon, pasynUser);
@ -510,6 +507,12 @@ connectToAsynPort()
return false;
}
}
// We probably should set REN=1 prior to sending but this
// seems to hang up the device every other time.
// if (pasynGpib)
// {
// pasynGpib->ren(pvtGpib, pasynUser, 1);
// }
return true;
}
@ -517,10 +520,12 @@ connectToAsynPort()
void AsynDriverInterface::
lockHandler()
{
int connected;
debug("AsynDriverInterface::lockHandler(%s)\n",
clientName());
pasynManager->blockProcessCallback(pasynUser, false);
lockCallback(StreamIoSuccess);
connected = connectToAsynPort();
lockCallback(connected ? StreamIoSuccess : StreamIoFault);
}
// interface function: we don't need exclusive access any more
@ -1202,46 +1207,27 @@ connectRequest(unsigned long connecttimeout_ms)
void AsynDriverInterface::
connectHandler()
{
int connected;
asynStatus status;
pasynManager->isConnected(pasynUser, &connected);
debug("AsynDriverInterface::connectHandler %s is %s connected\n",
clientName(), connected ? "already" : "not yet");
if (!connected)
{
status = pasynCommon->connect(pvtCommon, pasynUser);
if (status != asynSuccess)
{
error("%s connectRequest: pasynCommon->connect() failed: %s\n",
clientName(), pasynUser->errorMessage);
connectCallback(StreamIoFault);
return;
}
}
connectCallback(StreamIoSuccess);
connectCallback(connectToAsynPort() ? StreamIoSuccess : StreamIoFault);
}
bool AsynDriverInterface::
disconnect()
disconnectRequest()
{
asynStatus status;
ioAction = Disconnect;
debug("AsynDriverInterface::disconnect %s\n",
debug("AsynDriverInterface::disconnectRequest %s\n",
clientName());
status = pasynManager->queueRequest(pasynUser,
asynQueuePriorityConnect, 0.0);
if (status != asynSuccess)
{
error("%s disconnect: pasynManager->queueRequest() failed: %s\n",
error("%s disconnectRequest: pasynManager->queueRequest() failed: %s\n",
clientName(), pasynUser->errorMessage);
return false;
}
// continues with:
// handleRequest() -> disconnectHandler()
// or handleTimeout()
// (does not expect callback)
return true;
}
@ -1261,9 +1247,11 @@ disconnectHandler()
{
error("%s connectRequest: pasynCommon->disconnect() failed: %s\n",
clientName(), pasynUser->errorMessage);
disconnectCallback(StreamIoFault);
return;
}
}
disconnectCallback(StreamIoSuccess);
}
void AsynDriverInterface::
@ -1273,6 +1261,12 @@ finish()
clientName());
cancelTimer();
ioAction = None;
// if (pasynGpib)
// {
// // Release GPIB device the the end of the protocol
// // to re-enable local buttons.
// pasynGpib->ren(pvtGpib, pasynUser, 0);
// }
debug("AsynDriverInterface::finish(%s) done\n",
clientName());
}
@ -1335,9 +1329,9 @@ void handleTimeout(asynUser* pasynUser)
interface->connectCallback(StreamIoTimeout);
break;
case Disconnect:
debug ("AsynDriverInterface %s: disconnect timeout\n",
error("AsynDriverInterface %s: disconnect timeout\n",
interface->clientName());
// not interested in callback
// should not happen because of infinite timeout
break;
// No AsyncRead here because we don't use timeout when polling
default:

View File

@ -89,7 +89,7 @@ connectRequest (unsigned long)
}
bool StreamBusInterface::
disconnect ()
disconnectRequest ()
{
return false;
}
@ -137,6 +137,11 @@ connectCallback(StreamIoStatus)
{
}
void StreamBusInterface::Client::
disconnectCallback(StreamIoStatus)
{
}
long StreamBusInterface::Client::
priority()
{

View File

@ -42,6 +42,7 @@ public:
const void* input, long size);
virtual void eventCallback(StreamIoStatus status);
virtual void connectCallback(StreamIoStatus status);
virtual void disconnectCallback(StreamIoStatus status);
virtual long priority();
virtual const char* name() = 0;
virtual const char* getInTerminator(size_t& length) = 0;
@ -86,7 +87,7 @@ public:
return businterface->connectRequest(timeout_ms);
}
bool busDisconnect() {
return businterface->disconnect();
return businterface->disconnectRequest();
}
};
@ -113,6 +114,8 @@ protected:
{ client->eventCallback(status); }
void connectCallback(StreamIoStatus status)
{ client->connectCallback(status); }
void disconnectCallback(StreamIoStatus status)
{ client->disconnectCallback(status); }
const char* getInTerminator(size_t& length)
{ return client->getInTerminator(length); }
const char* getOutTerminator(size_t& length)
@ -132,7 +135,7 @@ protected:
unsigned long replytimeout_ms); // supportsEvents() returns true
virtual void release();
virtual bool connectRequest(unsigned long connecttimeout_ms);
virtual bool disconnect();
virtual bool disconnectRequest();
virtual void finish();
// pure virtual

View File

@ -23,6 +23,12 @@
#include <ctype.h>
#include <stdlib.h>
#include <epicsExport.h>
int showAsyncErrors = 0;
extern "C" {
epicsExportAddress(int, showAsyncErrors);
}
enum Commands { end_cmd, in_cmd, out_cmd, wait_cmd, event_cmd, exec_cmd,
connect_cmd, disconnect_cmd };
const char* commandStr[] = { "end", "in", "out", "wait", "event", "exec",
@ -801,6 +807,8 @@ writeCallback(StreamIoStatus status)
flags &= ~WritePending;
if (status != StreamIoSuccess)
{
error("%s: write failed: %s\n",
name(), StreamIoStatusStr[status]);
finishProtocol(WriteTimeout);
return;
}
@ -921,7 +929,11 @@ readCallback(StreamIoStatus status,
finishProtocol(ReplyTimeout);
return 0;
case StreamIoFault:
error("%s: I/O error when reading from device\n", name());
error("%s: I/O error after reading %ld byte%s: \"%s%s\"\n",
name(),
inputBuffer.length(), inputBuffer.length()==1 ? "" : "s",
inputBuffer.length() > 20 ? "..." : "",
inputBuffer.expand(-20,20)());
finishProtocol(Fault);
return 0;
}
@ -985,7 +997,7 @@ readCallback(StreamIoStatus status,
}
// try to parse what we got
end = inputBuffer.length();
if (!(flags & AsyncMode))
if (!(flags & AsyncMode)||showAsyncErrors)
{
error("%s: Timeout after reading %ld byte%s \"%s%s\"\n",
name(), end, end==1 ? "" : "s", end > 20 ? "..." : "",
@ -1115,7 +1127,7 @@ matchInput()
}
if (consumed < 0)
{
if (!(flags & AsyncMode) && onMismatch[0] != in_cmd)
if ((!(flags & AsyncMode)||showAsyncErrors) && onMismatch[0] != in_cmd)
{
error("%s: Input \"%s%s\" does not match format %%%s\n",
name(), inputLine.expand(consumedInput, 20)(),
@ -1130,7 +1142,7 @@ matchInput()
flags &= ~Separator;
if (!matchValue(fmt, fieldAddress ? fieldAddress() : NULL))
{
if (!(flags & AsyncMode) && onMismatch[0] != in_cmd)
if ((!(flags & AsyncMode)||showAsyncErrors) && onMismatch[0] != in_cmd)
{
if (flags & ScanTried)
error("%s: Input \"%s%s\" does not match format %%%s\n",
@ -1160,7 +1172,7 @@ matchInput()
{
int i = 0;
while (commandIndex[i] >= ' ') i++;
if (!(flags & AsyncMode) && onMismatch[0] != in_cmd)
if ((!(flags & AsyncMode)||showAsyncErrors) && onMismatch[0] != in_cmd)
{
error("%s: Input \"%s%s\" too short."
" No match for \"%s\"\n",
@ -1173,7 +1185,7 @@ matchInput()
}
if (command != inputLine[consumedInput])
{
if (!(flags & AsyncMode) && onMismatch[0] != in_cmd)
if ((!(flags & AsyncMode)||showAsyncErrors) && onMismatch[0] != in_cmd)
{
int i = 0;
while (commandIndex[i] >= ' ') i++;
@ -1198,7 +1210,7 @@ matchInput()
long surplus = inputLine.length()-consumedInput;
if (surplus > 0 && !(flags & IgnoreExtraInput))
{
if (!(flags & AsyncMode) && onMismatch[0] != in_cmd)
if ((!(flags & AsyncMode)||showAsyncErrors) && onMismatch[0] != in_cmd)
{
error("%s: %ld byte%s surplus input \"%s%s\"\n",
name(), surplus, surplus==1 ? "" : "s",
@ -1510,8 +1522,23 @@ bool StreamCore::evalDisconnect()
finishProtocol(Fault);
return false;
}
evalCommand();
return true;
}
void StreamCore::
disconnectCallback(StreamIoStatus status)
{
switch (status)
{
case StreamIoSuccess:
evalCommand();
return;
default:
error("%s: Disconnect failed\n",
name());
finishProtocol(Fault);
return;
}
}
#include "streamReferences"

View File

@ -200,6 +200,7 @@ protected:
void eventCallback(StreamIoStatus status);
void execCallback(StreamIoStatus status);
void connectCallback(StreamIoStatus status);
void disconnectCallback(StreamIoStatus status);
const char* getInTerminator(size_t& length);
const char* getOutTerminator(size_t& length);