Пример #1
0
void
sp_writer_free_block (ShmBlock * block)
{
    shm_alloc_space_block_dec (block->ablock);
    sp_shm_area_dec (block->pipe, block->area);
    spalloc_free (ShmBlock, block);
}
Пример #2
0
static void
sp_dec (ShmPipe * self)
{
  self->use_count--;

  if (self->use_count > 0)
    return;

  while (self->shm_area)
    sp_shm_area_dec (self, self->shm_area);

  spalloc_free (ShmPipe, self);
}
Пример #3
0
int
sp_writer_resize (ShmPipe * self, size_t size)
{
    ShmArea *newarea;
    ShmArea *old_current;
    ShmClient *client;
    int c = 0;
    int pathlen;

    if (self->shm_area->shm_area_len == size)
        return 0;

    newarea = sp_open_shm (NULL, ++self->next_area_id, 1, self->perms, size);

    if (!newarea)
        return -1;

    old_current = self->shm_area;
    newarea->next = self->shm_area;
    self->shm_area = newarea;

    pathlen = strlen (newarea->shm_area_name) + 1;

    for (client = self->clients; client; client = client->next) {
        struct CommandBuffer cb = { 0 };

        if (!send_command (client->fd, &cb, COMMAND_CLOSE_SHM_AREA,
                           old_current->id))
            continue;

        cb.payload.new_shm_area.size = newarea->shm_area_len;
        cb.payload.new_shm_area.path_size = pathlen;
        if (!send_command (client->fd, &cb, COMMAND_NEW_SHM_AREA, newarea->id))
            continue;

        if (send (client->fd, newarea->shm_area_name, pathlen, MSG_NOSIGNAL) !=
                pathlen)
            continue;
        c++;
    }

    sp_shm_area_dec (self, old_current);


    return c;
}
Пример #4
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;
}
Пример #5
0
void
sp_close (ShmPipe * self)
{
    if (self->main_socket >= 0)
        close (self->main_socket);

    if (self->socket_path) {
        unlink (self->socket_path);
        free (self->socket_path);
    }

    while (self->clients)
        sp_writer_close_client (self, self->clients);

    while (self->shm_area) {
        sp_shm_area_dec (self, self->shm_area);
    }

    spalloc_free (ShmPipe, self);
}
Пример #6
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;
}
Пример #7
0
int
sp_client_recv_finish (ShmPipe * self, char *buf)
{
    ShmArea *shm_area = NULL;
    unsigned long offset;
    struct CommandBuffer cb = { 0 };

    for (shm_area = self->shm_area; shm_area; shm_area = shm_area->next) {
        if (buf >= shm_area->shm_area &&
                buf < shm_area->shm_area + shm_area->shm_area_len)
            break;
    }

    assert (shm_area);

    offset = buf - shm_area->shm_area;

    sp_shm_area_dec (self, shm_area);

    cb.payload.ack_buffer.offset = offset;
    return send_command (self->main_socket, &cb, COMMAND_ACK_BUFFER,
                         self->shm_area->id);
}
Пример #8
0
unsigned long
sp_client_recv (ShmPipe * self, char **buf)
{
    char *area_name = NULL;
    ShmArea *newarea, *oldarea;
    ShmArea *area;
    struct CommandBuffer cb;
    int retval;

    if (!recv_command (self->main_socket, &cb))
        return -1;

    switch (cb.type) {
    case COMMAND_NEW_SHM_AREA:
        assert (cb.payload.new_shm_area.path_size > 0);
        assert (cb.payload.new_shm_area.size > 0);

        area_name = malloc (cb.payload.new_shm_area.path_size);
        retval = recv (self->main_socket, area_name,
                       cb.payload.new_shm_area.path_size, 0);
        if (retval != cb.payload.new_shm_area.path_size) {
            free (area_name);
            return -3;
        }

        newarea = sp_open_shm (area_name, cb.area_id, 0, 0,
                               cb.payload.new_shm_area.size);
        free (area_name);
        if (!newarea)
            return -4;

        oldarea = self->shm_area;
        newarea->next = self->shm_area;
        self->shm_area = newarea;
        /*
           if (oldarea)
           sp_shm_area_dec (self, oldarea);
         */
        break;

    case COMMAND_CLOSE_SHM_AREA:
        for (area = self->shm_area; area; area = area->next) {
            if (area->id == cb.area_id) {
                sp_shm_area_dec (self, area);
                break;
            }
        }
        break;

    case COMMAND_NEW_BUFFER:
        assert (buf);
        for (area = self->shm_area; area; area = area->next) {
            if (area->id == cb.area_id) {
                *buf = area->shm_area + cb.payload.buffer.offset;
                sp_shm_area_inc (area);
                return cb.payload.buffer.size;
            }
        }
        return -23;

    default:
        return -99;
    }

    return 0;
}