struct nn_chunk *nn_chunk_alloc (size_t size, int type) { size_t sz; struct nn_chunk *self; /* Allocate the actual memory depending on the type. */ sz = size + sizeof (struct nn_chunk); switch (type) { case 0: self = nn_alloc (sz, "message chunk"); break; default: return NULL; } alloc_assert (self); /* Fill in the chunk header. */ self->tag = NN_CHUNK_TAG; self->offset = 0; nn_atomic_init (&self->refcount, 1); self->vfptr = &nn_chunk_default_vfptr; self->size = size; return self; }
void *nn_chunk_alloc (size_t size, int type) { size_t sz; struct nn_chunk *self; /* Allocate the actual memory depending on the type. */ sz = sizeof (struct nn_chunk) + 2 * sizeof (uint32_t) + size; switch (type) { case 0: self = nn_alloc (sz, "message chunk"); break; default: return NULL; } alloc_assert (self); /* Fill in the chunk header. */ nn_atomic_init (&self->refcount, 1); self->size = size; self->ffn = nn_chunk_default_free; /* Fill in the size of the empty space between the chunk header and the message. */ nn_putl ((uint8_t*) ((uint32_t*) (self + 1)), 0); /* Fill in the tag. */ nn_putl ((uint8_t*) ((((uint32_t*) (self + 1))) + 1), NN_CHUNK_TAG); return ((uint8_t*) (self + 1)) + 2 * sizeof (uint32_t); }
int main () { int sb; int i; int j; struct nn_thread threads [THREAD_COUNT]; /* Stress the shutdown algorithm. */ sb = test_socket (AF_SP, NN_PUB); test_bind (sb, SOCKET_ADDRESS); for (j = 0; j != TEST_LOOPS; ++j) { for (i = 0; i != THREAD_COUNT; ++i) nn_thread_init (&threads [i], routine, NULL); for (i = 0; i != THREAD_COUNT; ++i) nn_thread_term (&threads [i]); } test_close (sb); /* Test race condition of sending message while socket shutting down */ sb = test_socket (AF_SP, NN_PUSH); test_bind (sb, SOCKET_ADDRESS); for (j = 0; j != TEST_LOOPS; ++j) { for (i = 0; i != TEST2_THREAD_COUNT; ++i) nn_thread_init (&threads [i], routine2, NULL); nn_atomic_init(&active, TEST2_THREAD_COUNT); while (active.n) { (void) nn_send (sb, "hello", 5, NN_DONTWAIT); } for (i = 0; i != TEST2_THREAD_COUNT; ++i) nn_thread_term (&threads [i]); nn_atomic_term(&active); } test_close (sb); return 0; }
int nn_chunk_alloc (size_t size, int type, void **result) { size_t sz; struct nn_chunk *self; const size_t hdrsz = sizeof (struct nn_chunk) + 2 * sizeof (uint32_t); /* Compute total size to be allocated. Check for overflow. */ sz = hdrsz + size; if (nn_slow (sz < hdrsz)) return -ENOMEM; /* Allocate the actual memory depending on the type. */ switch (type) { case 0: self = nn_alloc (sz, "message chunk"); break; default: return -EINVAL; } if (nn_slow (!self)) return -ENOMEM; /* Fill in the chunk header. */ nn_atomic_init (&self->refcount, 1); self->size = size; self->ffn = nn_chunk_default_free; /* Fill in the size of the empty space between the chunk header and the message. */ nn_putl ((uint8_t*) ((uint32_t*) (self + 1)), 0); /* Fill in the tag. */ nn_putl ((uint8_t*) ((((uint32_t*) (self + 1))) + 1), NN_CHUNK_TAG); *result = ((uint8_t*) (self + 1)) + 2 * sizeof (uint32_t); return 0; }