Example #1
0
static int
sp_shmbuf_dec (ShmPipe * self, ShmBuffer * buf, ShmBuffer * prev_buf)
{
    buf->use_count--;

    if (buf->use_count == 0) {
        /* Remove from linked list */
        if (prev_buf)
            prev_buf->next = buf->next;
        else
            self->buffers = buf->next;

        shm_alloc_space_block_dec (buf->block);
        sp_shm_area_dec (self, buf->shm_area);
        spalloc_free1 (sizeof (ShmBuffer) + sizeof (int) * buf->num_clients, buf);
        return 0;
    }

    return 1;
}
Example #2
0
static int
sp_shmbuf_dec (ShmPipe * self, ShmBuffer * buf, ShmBuffer * prev_buf,
    ShmClient * client, void **tag)
{
  int i;
  int had_client = 0;

  /**
   * Remove client from the list of buffer users. Here we make sure that
   * if a client closes connection but already decremented the use count
   * for this buffer, but other clients didn't have time to decrement
   * buffer will not be freed too early in sp_writer_close_client.
   */
  for (i = 0; i < buf->num_clients; i++) {
    if (buf->clients[i] == client->fd) {
      buf->clients[i] = -1;
      had_client = 1;
      break;
    }
  }
  assert (had_client);

  buf->use_count--;

  if (buf->use_count == 0) {
    /* Remove from linked list */
    if (prev_buf)
      prev_buf->next = buf->next;
    else
      self->buffers = buf->next;

    if (tag)
      *tag = buf->tag;
    shm_alloc_space_block_dec (buf->ablock);
    sp_shm_area_dec (self, buf->shm_area);
    spalloc_free1 (sizeof (ShmBuffer) + sizeof (int) * buf->num_clients, buf);
    return 0;
  }
  return 1;
}
Example #3
0
int
sp_writer_send_buf (ShmPipe * self, char *buf, size_t size)
{
    ShmArea *area = NULL;
    unsigned long offset = 0;
    unsigned long bsize = size;
    ShmBuffer *sb;
    ShmClient *client = NULL;
    ShmAllocBlock *block = NULL;
    int i = 0;
    int c = 0;

    if (self->num_clients == 0)
        return 0;

    for (area = self->shm_area; area; area = area->next) {
        if (buf >= area->shm_area && buf < (area->shm_area + area->shm_area_len)) {
            offset = buf - area->shm_area;
            block = shm_alloc_space_block_get (area->allocspace, offset);
            assert (block);
            break;
        }
    }

    if (!block)
        return -1;

    sb = spalloc_alloc (sizeof (ShmBuffer) + sizeof (int) * self->num_clients);
    memset (sb, 0, sizeof (ShmBuffer));
    memset (sb->clients, -1, sizeof (int) * self->num_clients);
    sb->shm_area = area;
    sb->offset = offset;
    sb->size = size;
    sb->num_clients = self->num_clients;
    sb->block = block;

    for (client = self->clients; client; client = client->next) {
        struct CommandBuffer cb = { 0 };
        cb.payload.buffer.offset = offset;
        cb.payload.buffer.size = bsize;
        if (!send_command (client->fd, &cb, COMMAND_NEW_BUFFER, self->shm_area->id))
            continue;
        sb->clients[i++] = client->fd;
        c++;
    }

    if (c == 0) {
        spalloc_free1 (sizeof (ShmBuffer) + sizeof (int) * self->num_clients, sb);
        return 0;
    }

    sp_shm_area_inc (area);
    shm_alloc_space_block_inc (block);

    sb->use_count = c;

    sb->next = self->buffers;
    self->buffers = sb;

    return c;
}