Skip to content

Commit

Permalink
get fived resending / queue management right, fix misc. bugs too
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Meeks committed Jun 30, 2011
1 parent 26806aa commit 8385f84
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 58 deletions.
25 changes: 6 additions & 19 deletions 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 ...

Expand All @@ -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." ? :-)
Expand All @@ -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
Expand All @@ -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.
+ when the adjustments change etc.
69 changes: 46 additions & 23 deletions libraries/libreprap/comms.c
Expand Up @@ -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
Expand Down Expand Up @@ -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)
{
Expand All @@ -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;
Expand All @@ -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;
}
Expand Down
29 changes: 14 additions & 15 deletions libraries/libreprap/fived.c
Expand Up @@ -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);

Expand Down
3 changes: 2 additions & 1 deletion src/model.cpp
Expand Up @@ -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));
Expand Down

0 comments on commit 8385f84

Please sign in to comment.