2020-02-18 Fred Gleason <fredg@paravelsystems.com>

* Fixed a regression in the implmenetation of the 'Set Serial Trap'
	['SI'] RML that could cause deadlocks and intermittent operation.
This commit is contained in:
Fred Gleason 2020-02-18 08:13:03 -05:00
parent 15cd9954a0
commit 16f8154800
6 changed files with 45 additions and 32 deletions

View File

@ -19641,3 +19641,6 @@
switcher driver. switcher driver.
2020-02-17 Fred Gleason <fredg@paravelsystems.com> 2020-02-17 Fred Gleason <fredg@paravelsystems.com>
* Removed Q3Socket dependency from the vGuest switcher driver. * Removed Q3Socket dependency from the vGuest switcher driver.
2020-02-18 Fred Gleason <fredg@paravelsystems.com>
* Fixed a regression in the implmenetation of the 'Set Serial Trap'
['SI'] RML that could cause deadlocks and intermittent operation.

View File

@ -2,7 +2,7 @@
// //
// A class for trapping arbitrary character sequences. // A class for trapping arbitrary character sequences.
// //
// (C) Copyright 2002-2004,2016 Fred Gleason <fredg@paravelsystems.com> // (C) Copyright 2002-2020 Fred Gleason <fredg@paravelsystems.com>
// //
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License // it under the terms of the GNU Library General Public License
@ -37,7 +37,7 @@ RDCodeTrap::~RDCodeTrap()
void RDCodeTrap::addTrap(int id,const char *code,int length) void RDCodeTrap::addTrap(int id,const char *code,int length)
{ {
for(unsigned i=0;i<trap_events.size();i++) { for(int i=0;i<trap_events.size();i++) {
if(length==trap_events[i].length) { if(length==trap_events[i].length) {
if((trap_events[i].id==id)&& if((trap_events[i].id==id)&&
(!strncmp(code,trap_events[i].code,length))) { (!strncmp(code,trap_events[i].code,length))) {
@ -45,7 +45,7 @@ void RDCodeTrap::addTrap(int id,const char *code,int length)
} }
} }
} }
trap_events.push_back(RTrapEvent()); trap_events.push_back(RDTrapEvent());
trap_events.back().id=id; trap_events.back().id=id;
trap_events.back().code=new char[length]; trap_events.back().code=new char[length];
memcpy(trap_events.back().code,code,length); memcpy(trap_events.back().code,code,length);
@ -56,10 +56,10 @@ void RDCodeTrap::addTrap(int id,const char *code,int length)
void RDCodeTrap::removeTrap(int id) void RDCodeTrap::removeTrap(int id)
{ {
for(unsigned i=0;i<trap_events.size();i++) { for(int i=0;i<trap_events.size();i++) {
if(trap_events[i].id==id) { if(trap_events[i].id==id) {
delete trap_events[i].code; delete trap_events[i].code;
vector<RTrapEvent>::iterator it=trap_events.begin()+i; QList<RDTrapEvent>::iterator it=trap_events.begin()+i;
trap_events.erase(it,it+1); trap_events.erase(it,it+1);
i--; i--;
} }
@ -69,11 +69,11 @@ void RDCodeTrap::removeTrap(int id)
void RDCodeTrap::removeTrap(const char *code,int length) void RDCodeTrap::removeTrap(const char *code,int length)
{ {
for(unsigned i=0;i<trap_events.size();i++) { for(int i=0;i<trap_events.size();i++) {
if(length==trap_events[i].length) { if(length==trap_events[i].length) {
if(!strncmp(code,trap_events[i].code,length)) { if(!strncmp(code,trap_events[i].code,length)) {
delete trap_events[i].code; delete trap_events[i].code;
vector<RTrapEvent>::iterator it=trap_events.begin()+i; QList<RDTrapEvent>::iterator it=trap_events.begin()+i;
trap_events.erase(it,it+1); trap_events.erase(it,it+1);
i--; i--;
} }
@ -84,12 +84,12 @@ void RDCodeTrap::removeTrap(const char *code,int length)
void RDCodeTrap::removeTrap(int id,const char *code,int length) void RDCodeTrap::removeTrap(int id,const char *code,int length)
{ {
for(unsigned i=0;i<trap_events.size();i++) { for(int i=0;i<trap_events.size();i++) {
if(length==trap_events[i].length) { if(length==trap_events[i].length) {
if((trap_events[i].id==id)&& if((trap_events[i].id==id)&&
(!strncmp(code,trap_events[i].code,length))) { (!strncmp(code,trap_events[i].code,length))) {
delete trap_events[i].code; delete trap_events[i].code;
vector<RTrapEvent>::iterator it=trap_events.begin()+i; QList<RDTrapEvent>::iterator it=trap_events.begin()+i;
trap_events.erase(it,it+1); trap_events.erase(it,it+1);
i--; i--;
} }
@ -100,7 +100,7 @@ void RDCodeTrap::removeTrap(int id,const char *code,int length)
void RDCodeTrap::scan(const char *buf,int length) void RDCodeTrap::scan(const char *buf,int length)
{ {
for(unsigned i=0;i<trap_events.size();i++) { for(int i=0;i<trap_events.size();i++) {
for(int j=0;j<length;j++) { for(int j=0;j<length;j++) {
if(buf[j]==trap_events[i].code[trap_events[i].istate]) { if(buf[j]==trap_events[i].code[trap_events[i].istate]) {
trap_events[i].istate++; trap_events[i].istate++;

View File

@ -2,7 +2,7 @@
// //
// A class for trapping arbitrary character sequences. // A class for trapping arbitrary character sequences.
// //
// (C) Copyright 2002-2004,2016 Fred Gleason <fredg@paravelsystems.com> // (C) Copyright 2002-2020 Fred Gleason <fredg@paravelsystems.com>
// //
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU Library General Public License // it under the terms of the GNU Library General Public License
@ -21,14 +21,10 @@
#ifndef RDCODETRAP_H #ifndef RDCODETRAP_H
#define RDCODETRAP_H #define RDCODETRAP_H
#include <vector> #include <qlist.h>
#include <qobject.h> #include <qobject.h>
using namespace std; struct RDTrapEvent {
struct RTrapEvent {
int id; int id;
char *code; char *code;
int length; int length;
@ -53,7 +49,7 @@ class RDCodeTrap : public QObject
void trapped(int id); void trapped(int id);
private: private:
vector<struct RTrapEvent> trap_events; QList<struct RDTrapEvent> trap_events;
}; };

View File

@ -2,7 +2,7 @@
// //
// Local RML Macros for the Rivendell Interprocess Communication Daemon // Local RML Macros for the Rivendell Interprocess Communication Daemon
// //
// (C) Copyright 2002-2019 Fred Gleason <fredg@paravelsystems.com> // (C) Copyright 2002-2020 Fred Gleason <fredg@paravelsystems.com>
// //
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as // it under the terms of the GNU General Public License version 2 as
@ -96,19 +96,22 @@ void MainObject::gpoStateData(int matrix,unsigned line,bool state)
void MainObject::ttyTrapData(int cartnum) void MainObject::ttyTrapData(int cartnum)
{ {
rda->syslog(LOG_DEBUG,"executing trap cart %06d",cartnum);
ExecCart(cartnum); ExecCart(cartnum);
} }
void MainObject::ttyScanData()
void MainObject::ttyReadyReadData(int num)
{ {
char buf[256]; char buf[256];
int n; int n;
for(int i=0;i<MAX_TTYS;i++) { if(ripcd_tty_dev[num]!=NULL) {
if(ripcd_tty_dev[i]!=NULL) { while((n=ripcd_tty_dev[num]->read(buf,255))>0) {
while((n=ripcd_tty_dev[i]->read(buf,255))>0) { buf[n]=0;
ripcd_tty_trap[i]->scan(buf,n); if(ripcd_tty_trap[num]!=NULL) {
ripcd_tty_trap[num]->scan(buf,n);
} }
} }
} }
@ -206,6 +209,10 @@ void MainObject::LoadLocalMacros()
ripcd_tty_dev[tty_port]-> ripcd_tty_dev[tty_port]->
setParity((RDTTYDevice::Parity)q->value(4).toInt()); setParity((RDTTYDevice::Parity)q->value(4).toInt());
if(ripcd_tty_dev[tty_port]->open(QIODevice::ReadWrite)) { if(ripcd_tty_dev[tty_port]->open(QIODevice::ReadWrite)) {
connect(ripcd_tty_dev[tty_port],SIGNAL(readyRead()),
ripcd_tty_ready_read_mapper,SLOT(map()));
ripcd_tty_ready_read_mapper->
setMapping(ripcd_tty_dev[tty_port],tty_port);
ripcd_tty_term[tty_port]=(RDTty::Termination)q->value(5).toInt(); ripcd_tty_term[tty_port]=(RDTty::Termination)q->value(5).toInt();
ripcd_tty_inuse[tty_port]=true; ripcd_tty_inuse[tty_port]=true;
ripcd_tty_trap[tty_port]=new RDCodeTrap(this); ripcd_tty_trap[tty_port]=new RDCodeTrap(this);
@ -219,9 +226,6 @@ void MainObject::LoadLocalMacros()
} }
} }
delete q; delete q;
QTimer *timer=new QTimer(this,"tty_scan_timer");
connect(timer,SIGNAL(timeout()),this,SLOT(ttyScanData()));
timer->start(RIPCD_TTY_READ_INTERVAL);
} }
@ -631,7 +635,7 @@ void MainObject::RunLocalMacros(RDMacro *rml_in)
sendRml(rml); sendRml(rml);
} }
break; break;
case RDMacro::SI: case RDMacro::SI:
tty_port=rml->arg(0).toInt(); tty_port=rml->arg(0).toInt();
if((tty_port<0)||(tty_port>MAX_TTYS)||(rml->argQuantity()!=3)) { if((tty_port<0)||(tty_port>MAX_TTYS)||(rml->argQuantity()!=3)) {
@ -652,6 +656,8 @@ void MainObject::RunLocalMacros(RDMacro *rml_in)
str+=rml->arg(rml->argQuantity()-1); str+=rml->arg(rml->argQuantity()-1);
ripcd_tty_trap[tty_port]->addTrap(rml->arg(1).toInt(), ripcd_tty_trap[tty_port]->addTrap(rml->arg(1).toInt(),
str,str.length()); str,str.length());
rda->syslog(LOG_DEBUG,"added trap \"%s\" to tty port %d",
(const char *)str.toUtf8(),rml->arg(1).toInt());
rml->acknowledge(true); rml->acknowledge(true);
sendRml(rml); sendRml(rml);
return; return;
@ -793,6 +799,7 @@ void MainObject::RunLocalMacros(RDMacro *rml_in)
// //
if(ripcd_tty_dev[tty_port]!=NULL) { if(ripcd_tty_dev[tty_port]!=NULL) {
ripcd_tty_dev[tty_port]->close(); ripcd_tty_dev[tty_port]->close();
ripcd_tty_ready_read_mapper->disconnect(ripcd_tty_dev[tty_port]);
delete ripcd_tty_dev[tty_port]; delete ripcd_tty_dev[tty_port];
ripcd_tty_dev[tty_port]=NULL; ripcd_tty_dev[tty_port]=NULL;
ripcd_tty_inuse[tty_port]=false; ripcd_tty_inuse[tty_port]=false;

View File

@ -2,7 +2,7 @@
// //
// Rivendell Interprocess Communication Daemon // Rivendell Interprocess Communication Daemon
// //
// (C) Copyright 2002-2019 Fred Gleason <fredg@paravelsystems.com> // (C) Copyright 2002-2020 Fred Gleason <fredg@paravelsystems.com>
// //
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as // it under the terms of the GNU General Public License version 2 as
@ -125,6 +125,13 @@ MainObject::MainObject(QObject *parent)
connect(ripc_macro_timer[i],SIGNAL(timeout()),mapper,SLOT(map())); connect(ripc_macro_timer[i],SIGNAL(timeout()),mapper,SLOT(map()));
} }
//
// TTY Ready Read Mapper
//
ripcd_tty_ready_read_mapper=new QSignalMapper(this);
connect(ripcd_tty_ready_read_mapper,SIGNAL(mapped(int)),
this,SLOT(ttyReadyReadData(int)));
ripcd_host_addr=rda->station()->address(); ripcd_host_addr=rda->station()->address();
// //

View File

@ -2,7 +2,7 @@
// //
// Rivendell Interprocess Communication Daemon // Rivendell Interprocess Communication Daemon
// //
// (C) Copyright 2002-2019 Fred Gleason <fredg@paravelsystems.com> // (C) Copyright 2002-2020 Fred Gleason <fredg@paravelsystems.com>
// //
// This program is free software; you can redistribute it and/or modify // This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as // it under the terms of the GNU General Public License version 2 as
@ -55,7 +55,6 @@
// //
#define RIPCD_MAX_LENGTH 256 #define RIPCD_MAX_LENGTH 256
#define RIPCD_RML_READ_INTERVAL 100 #define RIPCD_RML_READ_INTERVAL 100
#define RIPCD_TTY_READ_INTERVAL 100
#define RIPCD_USAGE "[-d]\n\nSupplying the '-d' flag will set 'debug' mode, causing ripcd(8) to stay\nin the foreground and print debugging info on standard output.\n" #define RIPCD_USAGE "[-d]\n\nSupplying the '-d' flag will set 'debug' mode, causing ripcd(8) to stay\nin the foreground and print debugging info on standard output.\n"
class MainObject : public QObject class MainObject : public QObject
@ -77,7 +76,7 @@ class MainObject : public QObject
void gpiStateData(int matrix,unsigned line,bool state); void gpiStateData(int matrix,unsigned line,bool state);
void gpoStateData(int matrix,unsigned line,bool state); void gpoStateData(int matrix,unsigned line,bool state);
void ttyTrapData(int cartnum); void ttyTrapData(int cartnum);
void ttyScanData(); void ttyReadyReadData(int num);
void macroTimerData(int num); void macroTimerData(int num);
void readyReadData(int conn_id); void readyReadData(int conn_id);
void killData(int conn_id); void killData(int conn_id);
@ -130,6 +129,7 @@ class MainObject : public QObject
bool ripcd_tty_inuse[MAX_TTYS]; bool ripcd_tty_inuse[MAX_TTYS];
int ripcd_switcher_tty[MAX_MATRICES][2]; int ripcd_switcher_tty[MAX_MATRICES][2];
RDTTYDevice *ripcd_tty_dev[MAX_TTYS]; RDTTYDevice *ripcd_tty_dev[MAX_TTYS];
QSignalMapper *ripcd_tty_ready_read_mapper;
RDTty::Termination ripcd_tty_term[MAX_TTYS]; RDTty::Termination ripcd_tty_term[MAX_TTYS];
RDCodeTrap *ripcd_tty_trap[MAX_TTYS]; RDCodeTrap *ripcd_tty_trap[MAX_TTYS];
bool ripc_onair_flag; bool ripc_onair_flag;