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.
2020-02-17 Fred Gleason <fredg@paravelsystems.com>
* 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.
//
// (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
// 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)
{
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((trap_events[i].id==id)&&
(!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().code=new char[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)
{
for(unsigned i=0;i<trap_events.size();i++) {
for(int i=0;i<trap_events.size();i++) {
if(trap_events[i].id==id) {
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);
i--;
}
@ -69,11 +69,11 @@ void RDCodeTrap::removeTrap(int id)
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(!strncmp(code,trap_events[i].code,length)) {
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);
i--;
}
@ -84,12 +84,12 @@ void RDCodeTrap::removeTrap(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((trap_events[i].id==id)&&
(!strncmp(code,trap_events[i].code,length))) {
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);
i--;
}
@ -100,7 +100,7 @@ void RDCodeTrap::removeTrap(int id,const char *code,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++) {
if(buf[j]==trap_events[i].code[trap_events[i].istate]) {
trap_events[i].istate++;

View File

@ -2,7 +2,7 @@
//
// 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
// it under the terms of the GNU Library General Public License
@ -21,14 +21,10 @@
#ifndef RDCODETRAP_H
#define RDCODETRAP_H
#include <vector>
#include <qlist.h>
#include <qobject.h>
using namespace std;
struct RTrapEvent {
struct RDTrapEvent {
int id;
char *code;
int length;
@ -53,7 +49,7 @@ class RDCodeTrap : public QObject
void trapped(int id);
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
//
// (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
// 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)
{
rda->syslog(LOG_DEBUG,"executing trap cart %06d",cartnum);
ExecCart(cartnum);
}
void MainObject::ttyScanData()
void MainObject::ttyReadyReadData(int num)
{
char buf[256];
int n;
for(int i=0;i<MAX_TTYS;i++) {
if(ripcd_tty_dev[i]!=NULL) {
while((n=ripcd_tty_dev[i]->read(buf,255))>0) {
ripcd_tty_trap[i]->scan(buf,n);
if(ripcd_tty_dev[num]!=NULL) {
while((n=ripcd_tty_dev[num]->read(buf,255))>0) {
buf[n]=0;
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]->
setParity((RDTTYDevice::Parity)q->value(4).toInt());
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_inuse[tty_port]=true;
ripcd_tty_trap[tty_port]=new RDCodeTrap(this);
@ -219,9 +226,6 @@ void MainObject::LoadLocalMacros()
}
}
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);
}
break;
case RDMacro::SI:
tty_port=rml->arg(0).toInt();
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);
ripcd_tty_trap[tty_port]->addTrap(rml->arg(1).toInt(),
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);
sendRml(rml);
return;
@ -793,6 +799,7 @@ void MainObject::RunLocalMacros(RDMacro *rml_in)
//
if(ripcd_tty_dev[tty_port]!=NULL) {
ripcd_tty_dev[tty_port]->close();
ripcd_tty_ready_read_mapper->disconnect(ripcd_tty_dev[tty_port]);
delete ripcd_tty_dev[tty_port];
ripcd_tty_dev[tty_port]=NULL;
ripcd_tty_inuse[tty_port]=false;

View File

@ -2,7 +2,7 @@
//
// 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
// 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()));
}
//
// 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();
//

View File

@ -2,7 +2,7 @@
//
// 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
// it under the terms of the GNU General Public License version 2 as
@ -55,7 +55,6 @@
//
#define RIPCD_MAX_LENGTH 256
#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"
class MainObject : public QObject
@ -77,7 +76,7 @@ class MainObject : public QObject
void gpiStateData(int matrix,unsigned line,bool state);
void gpoStateData(int matrix,unsigned line,bool state);
void ttyTrapData(int cartnum);
void ttyScanData();
void ttyReadyReadData(int num);
void macroTimerData(int num);
void readyReadData(int conn_id);
void killData(int conn_id);
@ -130,6 +129,7 @@ class MainObject : public QObject
bool ripcd_tty_inuse[MAX_TTYS];
int ripcd_switcher_tty[MAX_MATRICES][2];
RDTTYDevice *ripcd_tty_dev[MAX_TTYS];
QSignalMapper *ripcd_tty_ready_read_mapper;
RDTty::Termination ripcd_tty_term[MAX_TTYS];
RDCodeTrap *ripcd_tty_trap[MAX_TTYS];
bool ripc_onair_flag;