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 supportsEvent();
bool supportsAsyncRead(); bool supportsAsyncRead();
bool connectRequest(unsigned long connecttimeout_ms); bool connectRequest(unsigned long connecttimeout_ms);
bool disconnect(); bool disconnectRequest();
void finish(); void finish();
#ifdef EPICS_3_14 #ifdef EPICS_3_14
@ -462,11 +462,6 @@ lockRequest(unsigned long lockTimeout_ms)
clientName(), lockTimeout_ms); clientName(), lockTimeout_ms);
asynStatus status; asynStatus status;
lockTimeout = lockTimeout_ms ? lockTimeout_ms*0.001 : -1.0; lockTimeout = lockTimeout_ms ? lockTimeout_ms*0.001 : -1.0;
if (!lockTimeout_ms)
{
if (!connectToAsynPort()) return false;
}
ioAction = Lock; ioAction = Lock;
status = pasynManager->queueRequest(pasynUser, priority(), status = pasynManager->queueRequest(pasynUser, priority(),
lockTimeout); lockTimeout);
@ -497,6 +492,8 @@ connectToAsynPort()
clientName(), pasynUser->errorMessage); clientName(), pasynUser->errorMessage);
return false; return false;
} }
debug("AsynDriverInterface::connectToAsynPort(%s) is %s connected\n",
clientName(), connected ? "already" : "not yet");
if (!connected) if (!connected)
{ {
status = pasynCommon->connect(pvtCommon, pasynUser); status = pasynCommon->connect(pvtCommon, pasynUser);
@ -510,6 +507,12 @@ connectToAsynPort()
return false; 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; return true;
} }
@ -517,10 +520,12 @@ connectToAsynPort()
void AsynDriverInterface:: void AsynDriverInterface::
lockHandler() lockHandler()
{ {
int connected;
debug("AsynDriverInterface::lockHandler(%s)\n", debug("AsynDriverInterface::lockHandler(%s)\n",
clientName()); clientName());
pasynManager->blockProcessCallback(pasynUser, false); pasynManager->blockProcessCallback(pasynUser, false);
lockCallback(StreamIoSuccess); connected = connectToAsynPort();
lockCallback(connected ? StreamIoSuccess : StreamIoFault);
} }
// interface function: we don't need exclusive access any more // interface function: we don't need exclusive access any more
@ -1202,46 +1207,27 @@ connectRequest(unsigned long connecttimeout_ms)
void AsynDriverInterface:: void AsynDriverInterface::
connectHandler() connectHandler()
{ {
int connected; connectCallback(connectToAsynPort() ? StreamIoSuccess : StreamIoFault);
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);
} }
bool AsynDriverInterface:: bool AsynDriverInterface::
disconnect() disconnectRequest()
{ {
asynStatus status; asynStatus status;
ioAction = Disconnect; ioAction = Disconnect;
debug("AsynDriverInterface::disconnect %s\n", debug("AsynDriverInterface::disconnectRequest %s\n",
clientName()); clientName());
status = pasynManager->queueRequest(pasynUser, status = pasynManager->queueRequest(pasynUser,
asynQueuePriorityConnect, 0.0); asynQueuePriorityConnect, 0.0);
if (status != asynSuccess) if (status != asynSuccess)
{ {
error("%s disconnect: pasynManager->queueRequest() failed: %s\n", error("%s disconnectRequest: pasynManager->queueRequest() failed: %s\n",
clientName(), pasynUser->errorMessage); clientName(), pasynUser->errorMessage);
return false; return false;
} }
// continues with: // continues with:
// handleRequest() -> disconnectHandler() // handleRequest() -> disconnectHandler()
// or handleTimeout()
// (does not expect callback)
return true; return true;
} }
@ -1261,9 +1247,11 @@ disconnectHandler()
{ {
error("%s connectRequest: pasynCommon->disconnect() failed: %s\n", error("%s connectRequest: pasynCommon->disconnect() failed: %s\n",
clientName(), pasynUser->errorMessage); clientName(), pasynUser->errorMessage);
disconnectCallback(StreamIoFault);
return; return;
} }
} }
disconnectCallback(StreamIoSuccess);
} }
void AsynDriverInterface:: void AsynDriverInterface::
@ -1273,6 +1261,12 @@ finish()
clientName()); clientName());
cancelTimer(); cancelTimer();
ioAction = None; 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", debug("AsynDriverInterface::finish(%s) done\n",
clientName()); clientName());
} }
@ -1335,9 +1329,9 @@ void handleTimeout(asynUser* pasynUser)
interface->connectCallback(StreamIoTimeout); interface->connectCallback(StreamIoTimeout);
break; break;
case Disconnect: case Disconnect:
debug ("AsynDriverInterface %s: disconnect timeout\n", error("AsynDriverInterface %s: disconnect timeout\n",
interface->clientName()); interface->clientName());
// not interested in callback // should not happen because of infinite timeout
break; break;
// No AsyncRead here because we don't use timeout when polling // No AsyncRead here because we don't use timeout when polling
default: default:

View File

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

View File

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

View File

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

View File

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