Skip to content

Commit

Permalink
Added mutex for gettng object model, incomplete fix for issue #995
Browse files Browse the repository at this point in the history
dc42 committed May 25, 2024
1 parent 59c90b8 commit 69e3441
Showing 5 changed files with 22 additions and 21 deletions.
11 changes: 7 additions & 4 deletions src/GCodes/GCodes.cpp
Original file line number Diff line number Diff line change
@@ -4933,10 +4933,13 @@ void GCodes::CheckReportDue(GCodeBuffer& gb, const StringRef& reply) const noexc
if (lastAuxStatusReportType >= 0 && platform.IsAuxEnabled(0) && gb.IsReportDue())
{
// Send a standard status response for PanelDue
OutputBuffer * const statusBuf =
(lastAuxStatusReportType == ObjectModelAuxStatusReportType) // PanelDueFirmware v3.2 or later, using M409 to retrieve object model
? reprap.GetModelResponse(&gb, "", "d99fi")
: GenerateJsonStatusResponse(lastAuxStatusReportType, -1, ResponseSource::AUX); // older PanelDueFirmware using M408
OutputBuffer * statusBuf;
{
MutexLocker lock(reprap.GetObjectModelReportMutex());
statusBuf = (lastAuxStatusReportType == ObjectModelAuxStatusReportType) // PanelDueFirmware v3.2 or later, using M409 to retrieve object model
? reprap.GetModelResponse(&gb, "", "d99fi")
: GenerateJsonStatusResponse(lastAuxStatusReportType, -1, ResponseSource::AUX); // older PanelDueFirmware using M408
}
if (statusBuf != nullptr)
{
platform.AppendAuxReply(0, statusBuf, true);
12 changes: 7 additions & 5 deletions src/GCodes/GCodes2.cpp
Original file line number Diff line number Diff line change
@@ -3127,12 +3127,14 @@ bool GCodes::HandleMcode(GCodeBuffer& gb, const StringRef& reply) THROWS(GCodeEx
{
lastAuxStatusReportType = ObjectModelAuxStatusReportType;
}
outBuf = reprap.GetModelResponse(&gb, key.c_str(), flags.c_str());
if (outBuf == nullptr)
{
OutputBuffer::ReleaseAll(outBuf);
// We don't delay and retry here, in case the user asked for too much of the object model in one go for the output buffers to contain it
reply.copy("{\"err\":-1}\n");
MutexLocker lock(reprap.GetObjectModelReportMutex()); // grab the mutex to prevent PanelDue retrieving the OM at the same time, which can result in running out of buffers
outBuf = reprap.GetModelResponse(&gb, key.c_str(), flags.c_str());
if (outBuf == nullptr)
{
// We don't delay and retry here, in case the user asked for too much of the object model in one go for the output buffers to contain it
reply.copy("{\"err\":-1}\n");
}
}
if (&gb == AuxGCode())
{
2 changes: 2 additions & 0 deletions src/Networking/HttpResponder.cpp
Original file line number Diff line number Diff line change
@@ -648,6 +648,8 @@ bool HttpResponder::GetJsonResponse(const char *_ecv_array request, OutputBuffer
OutputBuffer::ReleaseAll(response);
const char *const filterVal = GetKeyValue("key");
const char *const flagsVal = GetKeyValue("flags");

MutexLocker lock(reprap.GetObjectModelReportMutex()); // grab the mutex to prevent PanelDue retrieving the OM at the same time, which can result in running out of buffers
response = reprap.GetModelResponse(nullptr, filterVal, flagsVal);
}
#endif
12 changes: 3 additions & 9 deletions src/Platform/RepRap.cpp
Original file line number Diff line number Diff line change
@@ -151,8 +151,6 @@ extern "C" void hsmciIdle(uint32_t stBits, uint32_t dmaBits) noexcept

#endif //end if HAS_HIGH_SPEED_SD && !SAME5x

#if SUPPORT_OBJECT_MODEL

// Object model table and functions
// Note: if using GCC version 7.3.1 20180622 and lambda functions are used in this table, you must compile this file with option -std=gnu++17.
// Otherwise the table will be allocate in RAM instead of flash, which wastes too much RAM.
@@ -439,8 +437,6 @@ constexpr uint8_t RepRap::objectModelTableDescriptor[] =

DEFINE_GET_OBJECT_MODEL_TABLE(RepRap)

#endif

// RepRap member functions.

// Do nothing more in the constructor; put what you want in RepRap:Init()
@@ -493,6 +489,8 @@ static void CheckWatchBuffer(unsigned int module) noexcept
void RepRap::Init() noexcept
{
OutputBuffer::Init();
objectModelReportMutex.Create("ModelReport");

platform = new Platform();
#if HAS_SBC_INTERFACE
sbcInterface = new SbcInterface(); // needs to be allocated early on Duet 2 so as to avoid using any of the last 64K of RAM
@@ -1119,7 +1117,7 @@ bool RepRap::SpinTimeoutImminent() const noexcept
return ticksInSpinState >= HighMainTaskTicksInSpinState;
}

// Get the JSON status response for the web server (or later for the M105 command).
// Get the JSON status response for the web server or the M408 command.
// Type 1 is the ordinary JSON status response.
// Type 2 is the same except that static parameters are also included.
// Type 3 is the same but instead of static parameters we report print estimation values.
@@ -2297,8 +2295,6 @@ void RepRap::AppendStringArray(OutputBuffer *buf, const char *name, size_t numVa
buf->cat(']');
}

#if SUPPORT_OBJECT_MODEL

// Return a query into the object model, or return nullptr if no buffer available
// We append a newline to help PanelDue resync after receiving corrupt or incomplete data. DWC ignores it.
OutputBuffer *RepRap::GetModelResponse(const GCodeBuffer *_ecv_null gb, const char *key, const char *flags) const THROWS(GCodeException)
@@ -2336,8 +2332,6 @@ OutputBuffer *RepRap::GetModelResponse(const GCodeBuffer *_ecv_null gb, const ch
return outBuf;
}

#endif

// Send a beep. We send it to both PanelDue and the web interface.
void RepRap::Beep(unsigned int freq, unsigned int ms) noexcept
{
6 changes: 3 additions & 3 deletions src/Platform/RepRap.h
Original file line number Diff line number Diff line change
@@ -115,10 +115,8 @@ class RepRap INHERIT_OBJECT_MODEL
#endif

GCodeResult GetFileInfoResponse(const char *filename, OutputBuffer *&response, bool quitEarly) noexcept;

#if SUPPORT_OBJECT_MODEL
OutputBuffer *GetModelResponse(const GCodeBuffer *_ecv_null gb, const char *key, const char *flags) const THROWS(GCodeException);
#endif
Mutex& GetObjectModelReportMutex() noexcept { return objectModelReportMutex; }

void Beep(unsigned int freq, unsigned int ms) noexcept;
void SetMessage(const char *msg) noexcept;
@@ -192,6 +190,8 @@ class RepRap INHERIT_OBJECT_MODEL
PrintMonitor* printMonitor;
FansManager* fansManager;

Mutex objectModelReportMutex; // mutex used to limit concurrent reporting of object model, which may result in output buffer starvation

// Recording the first error message encountered in config.g
AutoStringHandle configErrorFilename;
unsigned int configErrorLine;

0 comments on commit 69e3441

Please sign in to comment.