summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorTony Garnock-Jones <tonyg@kcbbs.gen.nz>2009-04-30 00:07:05 +0100
committerTony Garnock-Jones <tonyg@kcbbs.gen.nz>2009-04-30 00:07:05 +0100
commit5ad7fc306e8a6fb18222a502b8881f39384c4076 (patch)
treeb07191390c3f282f1115624d2785222995151791 /examples
parent1426205b75f4e3d29cc7bdfcad2974ac2c45a97f (diff)
downloadrabbitmq-c-5ad7fc306e8a6fb18222a502b8881f39384c4076.tar.gz
Avoid leaking memory by being precise about when a delivery is
finished, which lets us recycle a connection's memory pool at exactly the right time.
Diffstat (limited to 'examples')
-rw-r--r--examples/amqp_listen.c97
1 files changed, 60 insertions, 37 deletions
diff --git a/examples/amqp_listen.c b/examples/amqp_listen.c
index e33b3ef..f759183 100644
--- a/examples/amqp_listen.c
+++ b/examples/amqp_listen.c
@@ -8,6 +8,7 @@
#include <amqp_framing.h>
#include <unistd.h>
+#include <assert.h>
#include "example_utils.h"
@@ -100,53 +101,75 @@ int main(int argc, char const * const *argv) {
amqp_frame_t frame;
int result;
+ amqp_basic_deliver_t *d;
+ amqp_basic_properties_t *p;
+ size_t body_target;
+ size_t body_received;
+
while (1) {
amqp_maybe_release_buffers(conn);
result = amqp_simple_wait_frame(conn, &frame);
printf("Result %d\n", result);
- if (result <= 0) goto shutdown;
+ if (result <= 0)
+ break;
- analyse_frame:
printf("Frame type %d, channel %d\n", frame.frame_type, frame.channel);
- if (frame.frame_type == AMQP_FRAME_METHOD) {
- printf("Method %s\n", amqp_method_name(frame.payload.method.id));
- if (frame.payload.method.id == AMQP_BASIC_DELIVER_METHOD) {
- amqp_basic_deliver_t *d = (amqp_basic_deliver_t *) frame.payload.method.decoded;
- amqp_basic_properties_t *p;
- printf("Delivery %llu, exchange %.*s routingkey %.*s\n",
- d->delivery_tag,
- (int) d->exchange.len, (char *) d->exchange.bytes,
- (int) d->routing_key.len, (char *) d->routing_key.bytes);
-
- result = amqp_simple_wait_frame(conn, &frame);
- if (result <= 0) goto shutdown;
- if (frame.frame_type != AMQP_FRAME_HEADER) {
- fprintf(stderr, "Expected header!");
- abort();
- }
- p = (amqp_basic_properties_t *) frame.payload.properties.decoded;
- if (p->_flags & AMQP_BASIC_CONTENT_TYPE_FLAG) {
- printf("Content-type: %.*s\n",
- (int) p->content_type.len, (char *) p->content_type.bytes);
- }
- printf("----\n");
-
- while (1) {
- result = amqp_simple_wait_frame(conn, &frame);
- if (result <= 0) goto shutdown;
- if (frame.frame_type != AMQP_FRAME_BODY) {
- printf("====\n");
- goto analyse_frame;
- }
- amqp_dump(frame.payload.body_fragment.bytes,
- frame.payload.body_fragment.len);
- }
- }
+ if (frame.frame_type != AMQP_FRAME_METHOD)
+ continue;
+
+ printf("Method %s\n", amqp_method_name(frame.payload.method.id));
+ if (frame.payload.method.id != AMQP_BASIC_DELIVER_METHOD)
+ continue;
+
+ d = (amqp_basic_deliver_t *) frame.payload.method.decoded;
+ printf("Delivery %llu, exchange %.*s routingkey %.*s\n",
+ d->delivery_tag,
+ (int) d->exchange.len, (char *) d->exchange.bytes,
+ (int) d->routing_key.len, (char *) d->routing_key.bytes);
+
+ result = amqp_simple_wait_frame(conn, &frame);
+ if (result <= 0)
+ break;
+
+ if (frame.frame_type != AMQP_FRAME_HEADER) {
+ fprintf(stderr, "Expected header!");
+ abort();
+ }
+ p = (amqp_basic_properties_t *) frame.payload.properties.decoded;
+ if (p->_flags & AMQP_BASIC_CONTENT_TYPE_FLAG) {
+ printf("Content-type: %.*s\n",
+ (int) p->content_type.len, (char *) p->content_type.bytes);
+ }
+ printf("----\n");
+
+ body_target = frame.payload.properties.body_size;
+ body_received = 0;
+
+ while (body_received < body_target) {
+ result = amqp_simple_wait_frame(conn, &frame);
+ if (result <= 0)
+ break;
+
+ if (frame.frame_type != AMQP_FRAME_BODY) {
+ fprintf(stderr, "Expected body!");
+ abort();
+ }
+
+ body_received += frame.payload.body_fragment.len;
+ assert(body_received <= body_target);
+
+ amqp_dump(frame.payload.body_fragment.bytes,
+ frame.payload.body_fragment.len);
+ }
+
+ if (body_received != body_target) {
+ /* Can only happen when amqp_simple_wait_frame returns <= 0 */
+ /* We break here to close the connection */
+ break;
}
}
}
- shutdown:
die_on_amqp_error(amqp_channel_close(conn, AMQP_REPLY_SUCCESS), "Closing channel");
die_on_amqp_error(amqp_connection_close(conn, AMQP_REPLY_SUCCESS), "Closing connection");
amqp_destroy_connection(conn);