summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiles Bader <miles@gnu.org>1995-07-31 20:01:27 +0000
committerMiles Bader <miles@gnu.org>1995-07-31 20:01:27 +0000
commitdc095770749d83d948f8bd294226c79a91f30256 (patch)
treed2893e8679bd5f74a105e6ee4ecbe97855501510
parent913ab2407329d98b523198655c5cf9b0fa097fff (diff)
(pipe_recv): Assert that a control packet should only have a source address
if there is no corresponding data packet. (pipe_send): Change the test to determine whether we should write a control packet, so that we only do so if we need to. Also, don't record the source address in control packets, as it's recorded in the following data packet anyway, and this prevents it from being dealloc'd twice.
-rw-r--r--libpipe/pipe.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/libpipe/pipe.c b/libpipe/pipe.c
index 73463acd..d0035cbb 100644
--- a/libpipe/pipe.c
+++ b/libpipe/pipe.c
@@ -19,6 +19,7 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <string.h> /* For bzero() */
+#include <assert.h>
#include <mach/time_value.h>
#include <mach/mach_host.h>
@@ -114,11 +115,16 @@ pipe_send (struct pipe *pipe, void *source,
if (pipe->flags & PIPE_BROKEN)
return EPIPE;
- if (control || ports)
+ if (control_len > 0 || num_ports > 0)
/* Write a control packet. */
{
+ /* Note that we don't record the source address in control packets, as
+ it's recorded in the following data packet anyway, and this prevents
+ it from being dealloc'd twice; this depends on the fact that we
+ always write a data packet. */
struct packet *control_packet =
- pq_queue (pipe->queue, PACKET_TYPE_CONTROL, source);
+ pq_queue (pipe->queue, PACKET_TYPE_CONTROL, NULL);
+
if (control_packet == NULL)
err = ENOBUFS;
else
@@ -206,13 +212,19 @@ pipe_recv (struct pipe *pipe, int noblock, unsigned *flags, void **source,
packet_read_ports (packet, ports, num_ports);
packet_read_source (packet, &control_source);
+
packet = pq_next (pq, PACKET_TYPE_DATA, control_source);
- if (!packet && source)
- /* Since there is no data, say where the control data came from. */
- *source = control_source;
- else if (control_source)
- /* Otherwise be sure to get rid of our reference to the address. */
- pipe_dealloc_addr (control_source);
+
+ /* Control packets should only have a source address if they're not
+ followed by a data packet. */
+ assert (!!packet == !control_source);
+
+ if (!packet)
+ if (source)
+ /* Since there is no data, say where the control data came from. */
+ *source = control_source;
+ else
+ pipe_dealloc_addr (control_source);
}
else
/* No control data... */