AutoCheckWaySingleStep and some uninitialized memory fixed.

master
Steffen Pohle 2 years ago
parent 4a4735ab33
commit 63e9778929

@ -1,3 +1,6 @@
2024-01-16:
- fixed: not all pthread_mutexes has been initialization.
2023-12-30: 2023-12-30:
- fixed: FindWay will check for loops between two blocks - fixed: FindWay will check for loops between two blocks

@ -10,8 +10,10 @@
using namespace std; using namespace std;
Blocks::Blocks () { Blocks::Blocks () {
pthread_mutex_init(&mtx, NULL);
changed = 0; changed = 0;
blocks = (Block*) malloc(sizeof(Block)*SENSORS_MAX); blocks = (Block*) malloc(sizeof(Block)*SENSORS_MAX);
memset (blocks, 0x0, sizeof(Block)*SENSORS_MAX);
max = BLOCKS_MAX; max = BLOCKS_MAX;
last_blockidx = -1; last_blockidx = -1;
}; };

@ -2,32 +2,49 @@
// #define _GNU_SOURCE /* See feature_test_macros(7) */ // #define _GNU_SOURCE /* See feature_test_macros(7) */
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <execinfo.h> #include <execinfo.h>
#include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include <time.h>
#include <sys/syscall.h> #include <sys/syscall.h>
#include <sys/types.h>
#include <sys/time.h>
#include "modelbahn.h" #include "modelbahn.h"
#define DEBUG_FILE "/tmp/modelbahn-server.log" #define DEBUG_FILE "/tmp/modelbahn-server.log"
#define LEN_TEXT 256
int _debuglevel = 0xff; int _debuglevel = 0xff;
pid_t gettid(); pid_t gettid();
void debug (int type, char *fmt,...) { void debug (int type, char *fmt,...) {
va_list args; va_list args;
char texttime[LEN_TEXT];
char text1[DEBUG_TEXT1LEN]; char text1[DEBUG_TEXT1LEN];
char text2[DEBUG_TEXT2LEN]; char text2[DEBUG_TEXT2LEN];
pid_t pid = gettid(); pid_t pid = gettid();
int tms;
struct timeval tv;
struct tm tmp;
struct tm *tmptr = NULL;
va_start (args, fmt); va_start (args, fmt);
vsnprintf (text1, (DEBUG_TEXT1LEN-1), fmt, args); vsnprintf (text1, (DEBUG_TEXT1LEN-1), fmt, args);
va_end (args); va_end (args);
texttime[0] = 0;
text1[DEBUG_TEXT1LEN-1] = 0; text1[DEBUG_TEXT1LEN-1] = 0;
text2[DEBUG_TEXT2LEN-1] = 0; text2[DEBUG_TEXT2LEN-1] = 0;
if (type > 0) snprintf (text2, DEBUG_TEXT2LEN-1, "(%d)%d: %s", pid, type, text1); gettimeofday (&tv, NULL);
else snprintf (text2, DEBUG_TEXT2LEN-1, "(%d) %s", pid, text1); tmptr = localtime_r(&tv.tv_sec, &tmp);
if (tmptr != NULL)
strftime(texttime, LEN_TEXT, "%H:%M:%S", &tmp);
if (type > 0) snprintf (text2, DEBUG_TEXT2LEN-1, "(%d, %s.%03d) %d : %s", pid, texttime, tv.tv_usec/1000, type, text1);
else snprintf (text2, DEBUG_TEXT2LEN-1, "(%d, %s.%03d) : %s", pid, texttime, tv.tv_usec/1000, text1);
if (type == 0 || (type & _debuglevel) != 0) { if (type == 0 || (type & _debuglevel) != 0) {
FILE *f; FILE *f;

@ -15,6 +15,8 @@
Interfaces::Interfaces () { Interfaces::Interfaces () {
max = INTERFACES_MAX; max = INTERFACES_MAX;
pthread_mutex_init(&mtx, NULL);
for (int i = 0; i < max; i++) interfaces[i] = NULL; for (int i = 0; i < max; i++) interfaces[i] = NULL;
changed = 0; changed = 0;
}; };

@ -5,6 +5,7 @@
Locomotives::Locomotives () { Locomotives::Locomotives () {
pthread_mutex_init(&mtx, NULL);
changed = 0; changed = 0;
locomotives = (Locomotive*) malloc(sizeof(Locomotive)*LOCOMOTIVES_MAX); locomotives = (Locomotive*) malloc(sizeof(Locomotive)*LOCOMOTIVES_MAX);
memset(locomotives, 0x0, sizeof(Locomotive)*LOCOMOTIVES_MAX); memset(locomotives, 0x0, sizeof(Locomotive)*LOCOMOTIVES_MAX);
@ -703,7 +704,7 @@ int Locomotives::SchedulerNextStep(Locomotive *loc) {
// with each call only check one single step of the way, if we have to // with each call only check one single step of the way, if we have to
// turn a turnout try to do it and return 0. // turn a turnout try to do it and return 0.
// if everything is set up till the destination (next) block return 1 // if everything is set up till the destination (next) block return 1
// to speed things up: we only prepare ways wich we have locked already // to speed things up: we only prepare ways which we have locked already
// //
int Locomotives::AutoCheckWaySingleStep(string way, string locname, int *data) { int Locomotives::AutoCheckWaySingleStep(string way, string locname, int *data) {
int res = 0; int res = 0;
@ -719,10 +720,12 @@ int Locomotives::AutoCheckWaySingleStep(string way, string locname, int *data) {
if (*data < 0) *data = 0; if (*data < 0) *data = 0;
debug (0, "Locomotives::AutoCheckWaySingleStep Prepare for Loco: %s Way:%s", locname.c_str(), way.c_str()); debug (0, "Locomotives::AutoCheckWaySingleStep Prepare for Loco: %s Way:%s data:%d", locname.c_str(), way.c_str(), *data);
curpos = 0; curpos = 0;
do { do {
//
// read all ways from the begin with stop at "data"
curpos = way.find (",t:", curpos+1); curpos = way.find (",t:", curpos+1);
newdata++; newdata++;
if (curpos != string::npos) { if (curpos != string::npos) {
@ -747,27 +750,33 @@ int Locomotives::AutoCheckWaySingleStep(string way, string locname, int *data) {
while (server->railways.FindReference(&x, &y, turnout, cnt++)) { while (server->railways.FindReference(&x, &y, turnout, cnt++)) {
cnt++; cnt++;
r = server->railways.RailwayGet(x, y); r = server->railways.RailwayGet(x, y);
debug (0, "Locomotives::AutoCheckWaySingleStep Loco:%s Turnout: %s LockedBy:%s", locname.c_str(), turnout.c_str(), r.lockedby); debug (0, "Locomotives::AutoCheckWaySingleStep Loco:%s Turnout:%s LockedBy:%s", locname.c_str(), turnout.c_str(), r.lockedby);
if (locname.compare(r.lockedby) == 0) { //
//
if (locname.compare(r.lockedby) == 0 || r.lockedby[0] == 0) {
if (way[pos1+1] == '0' && state != 0) { if (way[pos1+1] == '0' && state != 0) {
debug (0, "Locomotives::AutoCheckWaySingleStep Loco:%s Turnout:%s Not Equal -> Set:0", locname.c_str(), turnout.c_str());
server->turnouts.Set(way.substr(curpos+3, pos1-curpos-3), 0); server->turnouts.Set(way.substr(curpos+3, pos1-curpos-3), 0);
break; return 0;
} }
else if (way[pos1+1] == '1' && state != 1) { else if (way[pos1+1] == '1' && state != 1) {
debug (0, "Locomotives::AutoCheckWaySingleStep Loco:%s Turnout:%s Not Equal -> Set:1", locname.c_str(), turnout.c_str());
server->turnouts.Set(way.substr(curpos+3, pos1-curpos-3), 1); server->turnouts.Set(way.substr(curpos+3, pos1-curpos-3), 1);
break; return 0;
} }
else if (newdata > *data) { else if (newdata > *data) {
debug (0, "Locomotives::AutoCheckWaySingleStep Loco:%s Turnout:%s Equal Reset:%c", locname.c_str(), turnout.c_str(), way[pos1+1]);
if (way[pos1+1] == '0') server->turnouts.Set(way.substr(curpos+3, pos1-curpos-3), 0); if (way[pos1+1] == '0') server->turnouts.Set(way.substr(curpos+3, pos1-curpos-3), 0);
if (way[pos1+1] == '1') server->turnouts.Set(way.substr(curpos+3, pos1-curpos-3), 1); if (way[pos1+1] == '1') server->turnouts.Set(way.substr(curpos+3, pos1-curpos-3), 1);
(*data) = newdata; (*data) = newdata;
break; return 0;
} }
} }
} }
if (cnt == 0) { if (cnt == 0) {
debug (0, "Locomotives::AutoCheckWaySingleStep Loco:%s Turnout:%s Reference not found", locname.c_str(), turnout.c_str()); debug (0, "Locomotives::AutoCheckWaySingleStep Loco:%s Turnout:%s Reference not found", locname.c_str(), turnout.c_str());
return 0;
} }
} }
} while (curpos != string::npos); } while (curpos != string::npos);
@ -1176,7 +1185,7 @@ int Locomotives::Loop() {
case 1: case 1:
SetSpeed(loco->name, loco->flags & LOCO_F_REVERSE ? -loco->vmid : loco->vmid); SetSpeed(loco->name, loco->flags & LOCO_F_REVERSE ? -loco->vmid : loco->vmid);
loco->auto_onroute = LOCO_OR_ONTHEWAY; loco->auto_onroute = LOCO_OR_ONTHEWAY;
debug (0, "* Locomotive '%s' Way Prepared -> Speed: VMID", loco->name); debug (0, "* %s:%d Locomotive '%s' Way Prepared -> Speed: VMID", __FILE__, __LINE__, loco->name);
jp.Clear(); jp.Clear();
jp.AddObject("locomotive",_GetJSON(lnum)); jp.AddObject("locomotive",_GetJSON(lnum));
if(network) network->ChangeListPushToAll(jp.ToString()); if(network) network->ChangeListPushToAll(jp.ToString());
@ -1184,7 +1193,7 @@ int Locomotives::Loop() {
case 2: case 2:
SetSpeed(loco->name, loco->flags & LOCO_F_REVERSE ? -loco->vfast : loco->vfast); SetSpeed(loco->name, loco->flags & LOCO_F_REVERSE ? -loco->vfast : loco->vfast);
loco->auto_onroute = LOCO_OR_ONTHEWAY; loco->auto_onroute = LOCO_OR_ONTHEWAY;
debug (0, "* Locomotive '%s' Way Prepared -> Speed: VFAST", loco->name); debug (0, "* %s:%d Locomotive '%s' Way Prepared -> Speed: VFAST", __FILE__, __LINE__, loco->name);
jp.Clear(); jp.Clear();
jp.AddObject("locomotive",_GetJSON(lnum)); jp.AddObject("locomotive",_GetJSON(lnum));
if(network) network->ChangeListPushToAll(jp.ToString()); if(network) network->ChangeListPushToAll(jp.ToString());
@ -1216,7 +1225,7 @@ int Locomotives::Loop() {
case 1: case 1:
SetSpeed(loco->name, loco->flags & LOCO_F_REVERSE ? -loco->vmid : loco->vmid); SetSpeed(loco->name, loco->flags & LOCO_F_REVERSE ? -loco->vmid : loco->vmid);
loco->auto_onroute = LOCO_OR_ONTHEWAY; loco->auto_onroute = LOCO_OR_ONTHEWAY;
debug (0, "* Locomotive LOCO_OR_ENTERBLOCKNEXT '%s' Way Prepared -> Speed: VMID", loco->name); debug (0, "* %s:%d Locomotive LOCO_OR_ENTERBLOCKNEXT '%s' Way Prepared -> Speed: VMID", __FILE__, __LINE__, loco->name);
jp.Clear(); jp.Clear();
jp.AddObject("locomotive",_GetJSON(lnum)); jp.AddObject("locomotive",_GetJSON(lnum));
if(network) network->ChangeListPushToAll(jp.ToString()); if(network) network->ChangeListPushToAll(jp.ToString());

@ -23,6 +23,8 @@ int simulation = 0;
int main (int argc, char **argv) { int main (int argc, char **argv) {
int i; int i;
tzset(); // needed for localtime to work
// //
// setup signals // setup signals
// //

@ -40,7 +40,9 @@ int main (int argc, char **argv) {
ptr = buffer+inlen; ptr = buffer+inlen;
} }
if (inlen >= BUFFERSIZE-1) fprintf (logf, "read input puffer full.\n"); if (inlen >= BUFFERSIZE-1) fprintf (logf, "read input puffer full.\n");
fprintf (logf, "read from stdin %lud bytes\n", strlen(buffer)); fprintf (logf, "read from stdin %lu bytes\n", strlen(buffer));
// fprintf (logf, "%s\n", buffer);
fprintf (logf, "*************************************\n");
// //
// send data to server // send data to server
@ -54,7 +56,7 @@ int main (int argc, char **argv) {
i = u.ReadTimeout(buffer, BUFFERSIZE-1, 1000); i = u.ReadTimeout(buffer, BUFFERSIZE-1, 1000);
buffer[i] = 0; buffer[i] = 0;
fprintf (logf, "read from server %d bytes\n", i); fprintf (logf, "read from server %d bytes\n", i);
// fprintf (logf, "%s\n", buffer); fprintf (logf, "%s\n", buffer);
printf ("%s", buffer); printf ("%s", buffer);
} while (i == BUFFERSIZE-1); } while (i == BUFFERSIZE-1);
u.Close(); u.Close();

@ -29,11 +29,8 @@ Network::Network() {
thread = 0; thread = 0;
sessions.clear(); sessions.clear();
thread_running = 0; thread_running = 0;
mtx = { 0 }; pthread_mutex_init(&mtx, NULL);
mtx = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_init(&mtxsessions, NULL);
mtxsessions = { 0 };
mtxsessions = PTHREAD_MUTEX_INITIALIZER;
} }
Network::~Network() { Network::~Network() {
@ -197,6 +194,7 @@ int Network::ClientLoop(UNIX *client) {
JSONParse json; JSONParse json;
JSONParse jsonout; JSONParse jsonout;
JSONParse jelement; JSONParse jelement;
long int l;
bufferin[len] = 0; // prevent reading behind the data bufferin[len] = 0; // prevent reading behind the data
@ -274,8 +272,9 @@ int Network::ClientLoop(UNIX *client) {
jsonout.AddObject(je); jsonout.AddObject(je);
} }
s = jsonout.ToString(); s = jsonout.ToString();
// debug (0, "%s:%d ---> send:\n\n\n%s\n\n\n", __FILE__, __LINE__, s.c_str()); // printf ("***************************** %s:%d ---> send:\n\n\n%s\n\n\n", __FILE__, __LINE__, s.c_str());
client->Write((char*)s.c_str(), strlen(s.c_str())); l = client->Write((char*)s.c_str(), strlen(s.c_str()));
// printf ("\n\n Network::ClientLoop %s:%d strlen:%ld result:%ld \n\n\n", __FILE__, __LINE__, strlen(s.c_str()), l);
result = 1; result = 1;
} }
else { else {

@ -8,8 +8,7 @@ Railways::Railways() {
height = 0; height = 0;
width = 0; width = 0;
railways = NULL; railways = NULL;
mtx = { 0 }; pthread_mutex_init(&mtx, NULL);
mtx = PTHREAD_MUTEX_INITIALIZER;
changed = 0; changed = 0;
// //

@ -7,7 +7,9 @@
Sensors::Sensors () { Sensors::Sensors () {
changed = 0; changed = 0;
sensors = (Sensor*) malloc(sizeof(Sensor)*SENSORS_MAX); sensors = (Sensor*) malloc(sizeof(Sensor)*SENSORS_MAX);
memset (sensors, 0x0, sizeof(Sensor)*SENSORS_MAX);
max = SENSORS_MAX; max = SENSORS_MAX;
pthread_mutex_init(&mtx, NULL);
}; };

@ -24,10 +24,9 @@
int Server::Start() { int Server::Start() {
int err; int err;
pthread_attr_t attr;
mtx = { 0 };
mtx = PTHREAD_MUTEX_INITIALIZER;
thread_running = 1; thread_running = 1;
pthread_attr_t attr;
pthread_attr_init (&attr); pthread_attr_init (&attr);
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_JOINABLE); pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_JOINABLE);
err = pthread_create (&thread, &attr, ThreadEntry, this); err = pthread_create (&thread, &attr, ThreadEntry, this);
@ -41,6 +40,9 @@ int Server::Start() {
Server::Server() { Server::Server() {
mtx = { 0 };
mtx = PTHREAD_MUTEX_INITIALIZER;
thread = 0; thread = 0;
thread_running = 0; thread_running = 0;
railways.SetSize(64, 32); railways.SetSize(64, 32);

@ -190,8 +190,10 @@ int Session::ProcessData(JSONParse *jin, JSONParse *jout) {
// debuggin maybe we need to fix this somehow // debuggin maybe we need to fix this somehow
elements = json.GetElements(); elements = json.GetElements();
for (iter = elements.begin(); iter != elements.end(); iter++) for (iter = elements.begin(); iter != elements.end(); iter++) {
// printf ("*********************** Session::ProcessData %s:%d\n\n***\n%s\n***\n", __FILE__, __LINE__, (*iter).GetString().c_str());
ChangeListPush("{"+(*iter).GetString()+"}"); ChangeListPush("{"+(*iter).GetString()+"}");
}
} }
else { else {
debug (DEBUG_ERROR | DEBUG_SESSION, "%s:%d Unknown command: '%s' JSON:%s", debug (DEBUG_ERROR | DEBUG_SESSION, "%s:%d Unknown command: '%s' JSON:%s",

@ -5,7 +5,9 @@
Turnouts::Turnouts() { Turnouts::Turnouts() {
changed = 0; changed = 0;
turnouts = (Turnout*) malloc(sizeof(Turnout)*TURNOUTS_MAX); turnouts = (Turnout*) malloc(sizeof(Turnout)*TURNOUTS_MAX);
memset (turnouts, 0x0, sizeof(Turnout)*TURNOUTS_MAX);
max = TURNOUTS_MAX; max = TURNOUTS_MAX;
pthread_mutex_init(&mtx, NULL);
}; };
Turnouts::~Turnouts() { Turnouts::~Turnouts() {

Loading…
Cancel
Save