aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Selkirk <paul@psgd.org>2017-03-02 17:34:42 -0500
committerPaul Selkirk <paul@psgd.org>2017-03-02 17:34:42 -0500
commit7a8a2564c64894026e6e79eb116f5b8b358d622c (patch)
tree415f2cd70231cea8f312bcce27236c2364f92d0e
parenta6d363b5e32ddf2d8281db52d55d1b63b74c67e9 (diff)
Try to be a bit more robust in the face of normal errors.
If hal_rpc_server_dispatch() returns an XDR decode error because the request packet was too short, don't call Error_Handler() and kill the dispatch thread, just drop the request. Add more ibuf_queue entries, but don't panic and kill the dispatch thread if we can't get one, just drop the incoming character (which will lead to an XDR decode error if/when we finally get an ibuf).
-rw-r--r--projects/hsm/hsm.c26
1 files changed, 16 insertions, 10 deletions
diff --git a/projects/hsm/hsm.c b/projects/hsm/hsm.c
index c2f6e0e..60e35fc 100644
--- a/projects/hsm/hsm.c
+++ b/projects/hsm/hsm.c
@@ -3,7 +3,7 @@
* ----------------
* Main module for the HSM project.
*
- * Copyright (c) 2016, NORDUnet A/S All rights reserved.
+ * Copyright (c) 2016-2017, NORDUnet A/S All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -94,13 +94,18 @@ typedef struct {
/* A mail queue (memory pool + message queue) for RPC request messages.
*/
osMailQId ibuf_queue;
-osMailQDef(ibuf_queue, NUM_RPC_TASK, rpc_buffer_t);
+osMailQDef(ibuf_queue, NUM_RPC_TASK + 2, rpc_buffer_t);
#if NUM_RPC_TASK > 1
/* A mutex to arbitrate concurrent UART transmits, from RPC responses.
*/
osMutexId uart_mutex;
osMutexDef(uart_mutex);
+static inline void uart_lock(void) { osMutexWait(uart_mutex, osWaitForever); }
+static inline void uart_unlock(void) { osMutexRelease(uart_mutex); }
+#else
+static inline void uart_lock(void) { }
+static inline void uart_unlock(void) { }
#endif
#if NUM_RPC_TASK > 1
@@ -130,7 +135,13 @@ static void RxCallback(uint8_t c)
if (ibuf == NULL) {
if ((ibuf = (rpc_buffer_t *)osMailAlloc(ibuf_queue, 0)) == NULL)
- Error_Handler();
+ /* This could happen if all dispatch threads are busy, and
+ * there are NUM_RPC_TASK requests already queued. We'd like
+ * to to send a "server busy" error, but we've just received
+ * the first byte of the request, so we don't yet have enough
+ * context to craft a response.
+ */
+ return;
ibuf->len = 0;
}
@@ -185,7 +196,6 @@ void dispatch_thread(void const *args)
hal_error_t ret = hal_rpc_server_dispatch(ibuf->buf, ibuf->len, obuf->buf, &obuf->len);
osMailFree(ibuf_queue, (void *)ibuf);
if (ret != LIBHAL_OK) {
- Error_Handler();
/* If hal_rpc_server_dispatch failed with an XDR error, it
* probably means the request packet was garbage. In any case, we
* have nothing to transmit.
@@ -194,13 +204,9 @@ void dispatch_thread(void const *args)
}
/* Send the response */
-#if NUM_RPC_TASK > 1
- osMutexWait(uart_mutex, osWaitForever);
-#endif
+ uart_lock();
ret = hal_rpc_sendto(obuf->buf, obuf->len, NULL);
-#if NUM_RPC_TASK > 1
- osMutexRelease(uart_mutex);
-#endif
+ uart_unlock();
if (ret != LIBHAL_OK)
Error_Handler();
}