diff --git a/TODO b/TODO index c14181fa..881a640a 100644 --- a/TODO +++ b/TODO @@ -1,5 +1,9 @@ --- the plan --- +* libreprap: + + don't write anything (particularly a re-send) while + a partial read is underway [?] + * sort out stdafx.h includes - check whether it is needed, and where ... @@ -10,9 +14,6 @@ + you need to tweak permissions, or add yourself to XYZ group, and re-login ... -* Settings re-factor - + stop Model being a widget ... - * Finish the 'Display' settings page * add Hardware Settings profiles: + "Mendel", "XYZ", "etc." ? :-) @@ -25,14 +26,7 @@ * win32 osc build fun ... ---- misc stuff --- - -* make toolkit lock sane and truly recursive - + to avoid gdk threads deadlock[!] - -* serial - + move ModelViewController DetectComPorts to RepRapSerial ... - ditto ValidateComPort +--- older stuff --- * connection button + should require confirmation before going off-line @@ -48,17 +42,10 @@ * add click-to-select in the 3D view -* re-factor MVC - * rename view.cpp etc. to render.cpp - * include SpinRows in view.cpp ... - * split chunks of model.cpp to view.cpp etc. - * split out / create an 'RFOView' widget to (sanely) - manipulate that treeview - * bug fixing: + arcball / rotation resetting ... + re-instate a non-gui mode ... * add log scrolling: + gtk_text_view_scroll_to_iter [etc.] - + when the adjustments change etc. \ No newline at end of file + + when the adjustments change etc. diff --git a/libraries/libreprap/comms.c b/libraries/libreprap/comms.c index f5e7cbf6..cce040af 100644 --- a/libraries/libreprap/comms.c +++ b/libraries/libreprap/comms.c @@ -89,18 +89,23 @@ rr_dev_pop_from_queue (rr_dev dev, rr_prio priority) } static void -empty_buffers (rr_dev dev) +empty_queue (rr_dev dev, int prio) { - unsigned i; - for (i = 0; i < RR_PRIO_ALL_QUEUES; ++i) { - while (dev->sendhead[i]) { - blocknode *node = rr_dev_pop_from_queue (dev, i); - blocknode_free (node); - } - assert (dev->sendhead[i] == NULL); - assert (dev->sendtail[i] == NULL); - dev->sendsize[i] = 0; + while (dev->sendhead[prio]) { + blocknode *node = rr_dev_pop_from_queue (dev, prio); + blocknode_free (node); } + assert (dev->sendhead[prio] == NULL); + assert (dev->sendtail[prio] == NULL); + dev->sendsize[prio] = 0; +} + +static void +empty_buffers (rr_dev dev) +{ + unsigned int i; + for (i = 0; i < RR_PRIO_ALL_QUEUES; ++i) + empty_queue (dev, i); } rr_dev @@ -305,13 +310,6 @@ rr_dev_enqueue_internal (rr_dev dev, rr_prio priority, return 0; } -/* - * FIXME - this needs to handle a jump-ahead use-case too ... - * we can get: - * rs 2 [and resend N2 ...] followed immediately by rs 6 ... - * and we need to do the converse - shift lines from the - * resend queue back onto the sentcache ... - */ int rr_dev_resend (rr_dev dev, unsigned long lineno, const char *reply, size_t nbytes) { @@ -322,21 +320,43 @@ rr_dev_resend (rr_dev dev, unsigned long lineno, const char *reply, size_t nbyte while (1) { if (!(node = rr_dev_pop_from_queue (dev, RR_PRIO_SENTCACHE))) break; - debug_log ((dev, "; pop node line %d '%s' (%d bytes)\n", + debug_log ((dev, "; pop sent node line %d '%s' (%d bytes)\n", (int)node->line, node->block, node->blocksize)); if (node->line >= lineno) { rr_dev_prepend_to_queue (dev, RR_PRIO_RESEND, node); resent++; - } else { /* put it back and exit */ + } else { /* put it back and look elsewhere */ rr_dev_prepend_to_queue (dev, RR_PRIO_SENTCACHE, node); break; } } - if (resent == 0) { /* Line needed for resend was not cached */ - rr_dev_log (dev, "; re-send request for unknown (too old) line %ld from cache size %d\n", - lineno, dev->sendsize[RR_PRIO_SENTCACHE]); - rr_dev_emit_error (dev, RR_E_UNCACHED_RESEND, reply, nbytes); + if (resent == 0) { + /* Perhaps line is in the resend queue, and we got an: + * rs: 3 + * rs: 6 + * type sequence so try peel forward the resend queue. + */ + + while (1) { + if (!(node = rr_dev_pop_from_queue (dev, RR_PRIO_RESEND))) + break; + debug_log ((dev, "; pop resend node line %d '%s' (%d bytes)\n", + (int)node->line, node->block, node->blocksize)); + if (node->line < lineno) { + rr_dev_prepend_to_queue (dev, RR_PRIO_SENTCACHE, node); + resent++; + } else { /* put it back and give up */ + rr_dev_prepend_to_queue (dev, RR_PRIO_RESEND, node); + break; + } + } + + if (resent == 0) { + rr_dev_log (dev, "; re-send request for unknown (too old) line %ld from cache size %d\n", + lineno, dev->sendsize[RR_PRIO_SENTCACHE]); + rr_dev_emit_error (dev, RR_E_UNCACHED_RESEND, reply, nbytes); + } } dev->send_next = 1; @@ -349,6 +369,9 @@ void rr_dev_reset_lineno (rr_dev dev) { dev->lineno = 0; + /* we invalidate all these line numbers */ + empty_queue (dev, RR_PRIO_RESEND); + empty_queue (dev, RR_PRIO_SENTCACHE); rr_dev_enqueue_internal (dev, RR_PRIO_HIGH, "M110", 4, -1); dev->init_send_count = dev->dev_cmdqueue_size - 1; } diff --git a/libraries/libreprap/fived.c b/libraries/libreprap/fived.c index 28bf125f..7656b3bf 100644 --- a/libraries/libreprap/fived.c +++ b/libraries/libreprap/fived.c @@ -57,23 +57,22 @@ fived_handle_reply (rr_dev dev, const char *reply, size_t nbytes) size_t n_start = strcspn (reply, "123456789"); if (n_start) { long long lineno = strtoll (reply + n_start, NULL, 10); - /* check if lineno is in the range of sent lines*/ - if (lineno < dev->lineno) - return rr_dev_resend (dev, lineno, reply, nbytes); - else { - if (dev->lineno <= 1) { - /* oh dear - most likely we re-connected to a device that - had problems mid-flow, now we need to re-send the - line-number reset as if it was this line-no it is asking - for a re-send of, or there will be no peace */ - rr_dev_log (dev, "; resetting confused firmware with synthetic resend of line %d\n", - dev->lineno); - rr_dev_enqueue_internal (dev, RR_PRIO_HIGH, "M110", 4, lineno); - /* re-start the print */ - rr_dev_resend (dev, 0, "synthetic restart", 16); - } + + if (dev->lineno <= 1) { + /* + * oh dear - most likely we re-connected to a device that + * had problems mid-flow, now we need to re-send the + * line-number reset as if it was this line-no it is asking + * for a re-send of, or there will be no peace + */ + rr_dev_log (dev, "; resetting confused firmware with synthetic resend of line %d\n", + dev->lineno); + rr_dev_enqueue_internal (dev, RR_PRIO_HIGH, "M110", 4, lineno); + /* re-start the print */ + rr_dev_resend (dev, 0, "synthetic restart", 16); return rr_dev_emit_error (dev, RR_E_UNSENT_RESEND, reply, nbytes); } + return rr_dev_resend (dev, lineno, reply, nbytes); } else return rr_dev_emit_error (dev, RR_E_MALFORMED_RESEND_REQUEST, reply, nbytes); diff --git a/src/model.cpp b/src/model.cpp index 1b27cd71..edc955e0 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -742,7 +742,8 @@ bool Model::handle_dev_fd (Glib::IOCondition cond) if (result < 0) error ("Error reading from device!", strerror (errno)); } - if (cond & Glib::IO_OUT) { + // try to avoid reading and writing at exactly the same time + else if (cond & Glib::IO_OUT) { result = rr_dev_handle_writable (m_device); if (result < 0) error ("Error writing to device!", strerror (errno));