diff --git a/ChangeLog b/ChangeLog index b61cac1..f4e43db 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2021-01-31: +- locked turnouts can not anymore been set. +- assign loco and set destination is working now. + + 2021-01-19: - threading should be now more stable no deadlocks diff --git a/server/locomotive.cc b/server/locomotive.cc index a223c93..1b961a9 100644 --- a/server/locomotive.cc +++ b/server/locomotive.cc @@ -123,6 +123,7 @@ Locomotive Locomotives::GetLocomotiveFromJSON(JSONParse *j) { l.blockprev[0] = 0; l.auto_way[0] = 0; l.auto_onroute = 0; + l.auto_data = 0; l.auto_timenext = {0}; j->GetValue("name", &s); @@ -157,7 +158,6 @@ int Locomotives::Change(Locomotive *loco) { int ifree = -1; Lock(); - printf ("%s:%d Change Locomotive\n", __FILE__, __LINE__); for (i = 0; i < max; i++) { if (locomotives[i].name[0] != 0) { // found element @@ -214,6 +214,7 @@ int Locomotives::Delete(string name) { locomotives[i].flags = 0; locomotives[i].auto_way[0] = 0; locomotives[i].auto_onroute = -1; + locomotives[i].auto_data = -1; locomotives[i].auto_timenext = {0}; changed = 1; break; @@ -291,12 +292,10 @@ int Locomotives::SetDestination (string name, string block, int direction) { debug (0, "Locomotives::SetDestination (Name:%s Block:%s Direction:%d)\n", name.c_str(), block.c_str(), direction); if (direction) snprintf (locomotives[i].blockdest, REFERENCENAME_LEN, "-:%s", block.c_str()); else snprintf (locomotives[i].blockdest, REFERENCENAME_LEN, "+:%s", block.c_str()); - printf ("%s:%d Locomotive '%s' blockdest:%s\n", __FILE__, __LINE__, locomotives[i].name, locomotives[i].blockdest); break; } UnLock(); - printf ("%s:%d %s ************** finish me **************\n", __FILE__, __LINE__, __FUNCTION__); return 1; } @@ -323,7 +322,6 @@ int Locomotives::SetAssign (string name, string block, int direction) { UnLock(); while (server->railways.FindReference(&x, &y, block)) { - printf ("%s:%d Reference found at %d, %d\n", __FILE__, __LINE__, x, y); string bl = server->blocks.GetLockedby(block); if(bl.length() == 0 || bl.compare(name) == 0) { server->blocks.SetLockedby(block, name, 1); @@ -332,6 +330,8 @@ int Locomotives::SetAssign (string name, string block, int direction) { } printf ("%s:%d %s ************** finish me **************\n", __FILE__, __LINE__, __FUNCTION__); + printf ("%s:%d %s * clear old refferences from loco \n", __FILE__, __LINE__, __FUNCTION__); + printf ("%s:%d %s * stop loco \n", __FILE__, __LINE__, __FUNCTION__); return 1; } @@ -505,15 +505,19 @@ string Locomotives::GetName(int idx) { // turn a turnout try to do it and return 0 // if everything is set up till the destination block return 1 // -int Locomotives::AutoCheckWaySingleStep(string way, string locname) { +int Locomotives::AutoCheckWaySingleStep(string way, string locname, int *data) { int res = 0; size_t pos1, pos2; size_t curpos; int val, state; + int newdata = 0; + + if (*data < 0) *data = 0; curpos = 0; do { curpos = way.find (",t:", curpos+1); + newdata++; if (curpos != string::npos) { pos1 = way.find(":", curpos+3); if (pos1 == string::npos) { @@ -528,14 +532,19 @@ int Locomotives::AutoCheckWaySingleStep(string way, string locname) { } if (way[pos1+1] == '0' && state != 0) { - server->TurnoutSet(way.substr(curpos+3, pos1-curpos-3), 0); + server->turnouts.Set(way.substr(curpos+3, pos1-curpos-3), 0); break; } else if (way[pos1+1] == '1' && state != 1) { - server->TurnoutSet(way.substr(curpos+3, pos1-curpos-3), 1); + server->turnouts.Set(way.substr(curpos+3, pos1-curpos-3), 1); + break; + } + else if (newdata > *data) { + 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); + (*data) = newdata; break; } - printf ("%s:%d Checked:%s\n", __FILE__, __LINE__, way.substr(curpos+3, pos1-curpos-3).c_str()); } } while (curpos != string::npos); @@ -561,13 +570,14 @@ int Locomotives::Loop() { // only in automate do anything alone // if (loco->blockassign[0] == 0 || loco->blockdest[0] == 0) continue; + if (loco->auto_onroute == LOCO_OR_NOTHING) { timer_start(&loco->auto_timenext); loco->auto_onroute = LOCO_OR_SEARCH; } - if (loco->auto_onroute == LOCO_OR_SEARCH) { + + else if (loco->auto_onroute == LOCO_OR_SEARCH) { if (loco->auto_timenext.tv_sec == 0 || timer_get(&loco->auto_timenext) > 1000) { - printf ("%s:%d Locomotive::Loop '%s' auto_onroute:%d\n", __FILE__, __LINE__, loco->name, loco->auto_onroute); if (server->railways.FindWay(loco->blockassign, loco->blockdest, loco->name, &way)) { size_t pos; @@ -576,6 +586,7 @@ int Locomotives::Loop() { strncpy (loco->blocknext, way.substr(pos+3,string::npos).c_str(), REFERENCENAME_LEN); strncpy (loco->auto_way, way.c_str(), WAYDATA_LEN); if (server->railways.LockWay(way, loco->name) == 1) { + loco->auto_data = -1; loco->auto_onroute = LOCO_OR_PREPARE; } else timer_start(&loco->auto_timenext); @@ -587,7 +598,7 @@ int Locomotives::Loop() { else if (loco->auto_onroute == LOCO_OR_PREPARE) { if (loco->auto_timenext.tv_sec == 0 || timer_get(&loco->auto_timenext) > 1000) { - if (AutoCheckWaySingleStep(loco->auto_way, loco->name) == 1) + if (AutoCheckWaySingleStep(loco->auto_way, loco->name, &loco->auto_data) == 1) loco->auto_onroute = LOCO_OR_ONTHEWAY; else timer_start(&loco->auto_timenext); } @@ -657,11 +668,14 @@ int Locomotives::Loop() { int Locomotives::Test(string loco) { int res = 0; int i; + int j = 0; + + printf ("%s:%d LocoTest.\n", __FILE__, __LINE__); for (i = 0; i < max; i++) if (locomotives[i].name[0] != 0) if (loco.compare(locomotives[i].name) == 0) { - res = AutoCheckWaySingleStep(locomotives[i].auto_way, loco); + res = AutoCheckWaySingleStep(locomotives[i].auto_way, loco, &j); } printf ("%s:%d LocoTest ---> Return %d\n", __FILE__, __LINE__, res); diff --git a/server/locomotive.h b/server/locomotive.h index 575f531..61f32f1 100644 --- a/server/locomotive.h +++ b/server/locomotive.h @@ -63,6 +63,7 @@ struct s_Locomotive { char auto_way[WAYDATA_LEN]; // route to way "b:+blockname,t:name:0,t:name:1,b:-blockname" int auto_onroute; // LOCO_OR_.... + int auto_data; // just some data needed by some steps struct timeval auto_timenext; // timeval of the next active step } typedef Locomotive; @@ -101,7 +102,7 @@ class Locomotives { int SetDestination (string name, string block, int direction); int SetAssign (string name, string block, int direction); - int AutoCheckWaySingleStep(string way, string locname); + int AutoCheckWaySingleStep(string way, string locname, int *data); int Loop(); string GetName(int idx); diff --git a/server/server.cc b/server/server.cc index 7993a78..f362b85 100644 --- a/server/server.cc +++ b/server/server.cc @@ -59,6 +59,28 @@ Server::~Server() { }; +int Server::TurnoutSet(string name, int active) { + int x, y, locked = 0; + string lockedby; + Railway r; + // + // check if locked + while (server->railways.FindReference(&x, &y, name)) { + r = server->railways.Get(x, y); + printf ("Reference %d,%d Name:%s Lockedby:%d\n", x, y, r.name, r.lockedby); + if (r.lockedby[0] != 0) { + locked = 1; + lockedby = r.lockedby; + } + } + + if (locked == 0) return turnouts.Set(name, active); + else { + debug (0, "%s:%d SetJSONTurnout Element %s is locked by %s", __FILE__, __LINE__, name.c_str(), lockedby.c_str()); + } + + return 0; +} // // server thread will cycle as long as running is set to true diff --git a/server/server.h b/server/server.h index 300d9af..d291ea7 100644 --- a/server/server.h +++ b/server/server.h @@ -143,7 +143,7 @@ public: Turnout TurnoutFromJSON(JSONParse *j) { return turnouts.GetTurnoutFromJSON(j); }; JSONParse TurnoutGetJSON(string name) { return turnouts.GetJSON(name); }; int TurnoutDelete(string name) { return turnouts.Delete(name); }; - int TurnoutSet(string name, int active) { return turnouts.Set(name, active); }; + int TurnoutSet(string name, int active); ///////////////////////////////////////// // Interface diff --git a/server/session.cc b/server/session.cc index 839140f..35a885b 100644 --- a/server/session.cc +++ b/server/session.cc @@ -656,7 +656,11 @@ void Session::DelJSONTurnout(JSONParse *jp) { void Session::SetJSONTurnout(JSONParse *jp) { JSONParse jout; string name; + string lockedby; int active; + int x, y; + int locked = 0; + Railway r; server->LockThread();