コード例 #1
0
ファイル: task.c プロジェクト: bjornaugestad/highlander
// Grab a lock on the FIFO. Then do a condwait until we get a message.
//
status_t message_get(tid_t *sender, msgid_t *msg, msgarg_t *arg1, msgarg_t *arg2)
{
    struct message *pm;

    task p = self();

    // First lock the queue to see if there's a message available.
    if (!fifo_lock(p->q))
        return false;

    if (fifo_nelem(p->q) == 0) {
        if (!fifo_unlock(p->q))
            return false;

        if (!fifo_wait_cond(p->q))
            return false;
    }

    // We now hold a lock.
    assert(fifo_nelem(p->q) > 0);

    if ((pm = fifo_get(p->q)) == NULL)
        die("%s(): Internal error\n", __func__);

    *sender = pm->sender;
    *msg = pm->msg;
    *arg1 = pm->arg1;
    *arg2 = pm->arg2;

    fifo_unlock(p->q);
    free(pm);
    return success;
}
コード例 #2
0
ファイル: streambuf.c プロジェクト: gnalbandian/squeezeplay
static int stream_load_loopL(lua_State *L) {
	int fd;
	ssize_t n, len;
	char *filename;

	/*
	 * 1: self
	 * 2: file
	 */

	filename = alloca(PATH_MAX);
	if (!squeezeplay_find_file(lua_tostring(L, 2), filename)) {
		LOG_ERROR(log_audio_decode, "Can't find image %s\n", lua_tostring(L, 2));
		return 0;
	}


	if ((fd = open(filename, O_RDONLY)) < 0) {
		LOG_ERROR(log_audio_decode, "Can't open %s", lua_tostring(L, 2));
		return 0;
	}

	fifo_lock(&streambuf_fifo);

	streambuf_lptr = streambuf_fifo.wptr;
	streambuf_loop = TRUE;

	n = fifo_bytes_free(&streambuf_fifo);
	if ((len = read(fd, streambuf_buf + streambuf_fifo.wptr, n)) < 0) {
		goto read_err;
	}
	fifo_wptr_incby(&streambuf_fifo, len);

	n = fifo_bytes_free(&streambuf_fifo);
	if (n) {
		if ((n = read(fd, streambuf_buf + streambuf_fifo.wptr, n)) < 0) {
			goto read_err;
		}
		fifo_wptr_incby(&streambuf_fifo, n);
		len += n;
	}

	streambuf_streaming = FALSE;
	streambuf_bytes_received = len;
	streambuf_filter = streambuf_next_filter;
	streambuf_next_filter = NULL;

	fifo_unlock(&streambuf_fifo);
	close(fd);

	return 0;

 read_err:
	fifo_unlock(&streambuf_fifo);
	close(fd);

	return 0;
}
コード例 #3
0
ファイル: fifo.c プロジェクト: Themaister/libmaru
size_t maru_fifo_write_avail(maru_fifo *fifo)
{
   fifo_lock(fifo);
   size_t ret = maru_fifo_write_avail_nolock(fifo);
   fifo_unlock(fifo);
   return ret;
}
コード例 #4
0
ファイル: fifo.c プロジェクト: Themaister/libmaru
maru_error maru_fifo_read_lock(maru_fifo *fifo,
      size_t size, struct maru_fifo_locked_region *region)
{
   fifo_lock(fifo);

   size_t avail_first = fifo->buffer_size - fifo->read_lock_end;
   size_t read_first = size;
   if (read_first > avail_first)
      read_first = avail_first;
   size_t read_second = size - read_first;

   region->first = fifo->buffer + fifo->read_lock_end;
   region->first_size = read_first;
   region->second = read_second ? fifo->buffer : NULL;
   region->second_size = read_second;

   if (region->second_size)
      fifo->read_lock_end = region->second_size;
   else
      fifo->read_lock_end = (fifo->read_lock_end + region->first_size) & fifo->buffer_mask;

   fifo_unlock(fifo);

   return LIBMARU_SUCCESS;
}
コード例 #5
0
ファイル: streambuf.c プロジェクト: gnalbandian/squeezeplay
/* read bytes from the streaming socket and discard - used by network test to measure network throughput*/
static int stream_readtonullL(lua_State *L) {
	struct stream *stream;
	char buf[4094];
	int n;
	/*
	 * 1: Stream (self)
	 */

	stream = lua_touserdata(L, 1);

	n = recv(stream->fd, buf, sizeof(buf), 0);	

	if (n > 0) {
		fifo_lock(&streambuf_fifo);
		streambuf_bytes_received += n;
		fifo_unlock(&streambuf_fifo);
		lua_pushinteger(L, n);
		return 1;
	} else if (n == -1 && errno == EAGAIN) {
		lua_pushinteger(L, 0);
		return 1;
	} else {
		CLOSESOCKET(stream->fd);
		lua_pushnil(L);
		lua_pushstring(L, strerror(n));
		return 2;
	}
}
コード例 #6
0
ファイル: fifo.c プロジェクト: Themaister/libmaru
maru_error maru_fifo_read_unlock(maru_fifo *fifo,
      const struct maru_fifo_locked_region *region)
{
   maru_error ret = LIBMARU_SUCCESS;
   fifo_lock(fifo);

   // Check if ordering of unlocks differ from order of locks.
   if (fifo->buffer + fifo->read_lock_begin != region->first)
   {
      ret = LIBMARU_ERROR_INVALID;
      goto end;
   }

   size_t new_begin = (fifo->read_lock_begin + region->first_size) & fifo->buffer_mask;

   if (region->second_size && new_begin != 0)
   {
      ret = LIBMARU_ERROR_INVALID;
      goto end;
   }

   new_begin += region->second_size;
   fifo->read_lock_begin = new_begin;

   if (maru_fifo_write_avail_nolock(fifo) >= fifo->write_trigger && fifo->write_fd >= 0)
      eventfd_write(fifo->write_fd, 1);

end:
   fifo_unlock(fifo);
   return ret;
}
コード例 #7
0
ファイル: streambuf.c プロジェクト: gnalbandian/squeezeplay
void streambuf_set_filter(streambuf_filter_t filter) {
	fifo_lock(&streambuf_fifo);

	streambuf_next_filter = filter;

	fifo_unlock(&streambuf_fifo);
}
コード例 #8
0
ファイル: serial.c プロジェクト: Ant1r/Fraise
static unsigned char read_byte(void)
{
  unsigned char has_read = 0;
  unsigned char c = 0;

  while (!has_read)
    {
      int_wait();

      fifo_lock(&gfifo);

      if (gfifo.size)
	{
	  c = fifo_pop(&gfifo);
	  has_read = 1;
	}
      else if (gfifo.error)
	{
	  has_read = 1;
	}

      fifo_unlock(&gfifo);
    }

  return c;
}
コード例 #9
0
ファイル: streambuf.c プロジェクト: gnalbandian/squeezeplay
static void streambuf_feedL(u8_t *buf, size_t size, lua_State *L) {
	size_t n;

	fifo_lock(&streambuf_fifo);

	streambuf_streaming = TRUE;

	streambuf_bytes_received += size;

	while (size) {
		n = fifo_bytes_until_wptr_wrap(&streambuf_fifo);

		if (n > size) {
			n = size;
		}

		memcpy(streambuf_buf + streambuf_fifo.wptr, buf, n);

		proxy_chunk(streambuf_buf + streambuf_fifo.wptr, n, L);

		fifo_wptr_incby(&streambuf_fifo, n);
		buf  += n;
		size -= n;
	}

	fifo_unlock(&streambuf_fifo);
}
コード例 #10
0
ファイル: fifo.c プロジェクト: Themaister/libmaru
void maru_fifo_kill_notification(maru_fifo *fifo)
{
   fifo_lock(fifo);
   fifo->dead = true;
   eventfd_write(fifo->write_fd, 1);
   eventfd_write(fifo->read_fd, 1);
   fifo_unlock(fifo);
}
コード例 #11
0
ファイル: streambuf.c プロジェクト: gnalbandian/squeezeplay
void streambuf_flush(void) {
	fifo_lock(&streambuf_fifo);

	streambuf_fifo.rptr = 0;
	streambuf_fifo.wptr = 0;

	fifo_unlock(&streambuf_fifo);
}
コード例 #12
0
ファイル: fifo.c プロジェクト: Themaister/libmaru
maru_error maru_fifo_write_notify_ack(maru_fifo *fifo)
{
   fifo_lock(fifo);
   maru_error ret = fifo->dead ? LIBMARU_ERROR_DEAD : LIBMARU_SUCCESS;
   if (!fifo->dead)
      maru_fifo_write_notify_ack_nolock(fifo);
   fifo_unlock(fifo);
   return ret;
}
コード例 #13
0
ファイル: streambuf.c プロジェクト: gnalbandian/squeezeplay
static int stream_mark_loopL(lua_State *L) {
	fifo_lock(&streambuf_fifo);

	streambuf_loop = TRUE;

	fifo_unlock(&streambuf_fifo);

	return 0;
}
コード例 #14
0
ファイル: meta_fifo.c プロジェクト: bjornaugestad/highlander
status_t fifo_write_signal(fifo p, void *data)
{
    status_t rc;

    assert(p != NULL);
    assert(data != NULL);

    if (!fifo_lock(p))
        return failure;

    if (!fifo_add(p, data)) {
        fifo_unlock(p);
        return failure;
    }

    rc = fifo_signal(p);
    fifo_unlock(p);

    return rc;
}
コード例 #15
0
ファイル: streambuf.c プロジェクト: gnalbandian/squeezeplay
size_t streambuf_get_freebytes(void) {
	size_t n;

	fifo_lock(&streambuf_fifo);

	n = fifo_bytes_free(&streambuf_fifo);

	fifo_unlock(&streambuf_fifo);

	return n;
}
コード例 #16
0
ファイル: streambuf.c プロジェクト: gnalbandian/squeezeplay
void streambuf_get_status(size_t *size, size_t *usedbytes, u32_t *bytesL, u32_t *bytesH) {

	fifo_lock(&streambuf_fifo);

	*size = STREAMBUF_SIZE;
	*usedbytes = fifo_bytes_used(&streambuf_fifo);
	*bytesL = streambuf_bytes_received & 0xFFFFFFFF;
	*bytesH = streambuf_bytes_received >> 32;

	fifo_unlock(&streambuf_fifo);
}
コード例 #17
0
ファイル: streambuf.c プロジェクト: gnalbandian/squeezeplay
size_t streambuf_get_usedbytes(void) {
	size_t n;

	fifo_lock(&streambuf_fifo);

	n = fifo_bytes_used(&streambuf_fifo);

	fifo_unlock(&streambuf_fifo);

	return n;
}
コード例 #18
0
ファイル: meta_fifo.c プロジェクト: bjornaugestad/highlander
status_t fifo_wait_cond(fifo p)
{
    assert(p != NULL);

    if (!fifo_lock(p))
        return failure;

    if (!wlock_wait(p->lock)) {
        fifo_unlock(p);
        return failure;
    }

    /* OK, we have the lock. See if there are data or not.
     * No data means that fifo_wake() was called.
     */
    if (fifo_nelem(p) == 0) {
        fifo_unlock(p);
        return fail(ENOENT);
    }

    return success;
}
コード例 #19
0
ファイル: streambuf.c プロジェクト: gnalbandian/squeezeplay
ssize_t streambuf_feed_fd(int fd, lua_State *L) {
	ssize_t n, size;

	fifo_lock(&streambuf_fifo);

	streambuf_streaming = TRUE;

	size = fifo_bytes_free(&streambuf_fifo);
	if (size < 4096) {
		fifo_unlock(&streambuf_fifo);
		return -ENOSPC; /* no space */
	}

	n = fifo_bytes_until_wptr_wrap(&streambuf_fifo);
	if (n > size) {
		n = size;
	}

	n = recv(fd, streambuf_buf + streambuf_fifo.wptr, n, 0);
	if (n < 0) {
		streambuf_streaming = FALSE;

		fifo_unlock(&streambuf_fifo);
		return -SOCKETERROR;
	}
	else if (n == 0) {
		streambuf_streaming = FALSE;
	}
	else {
		proxy_chunk(streambuf_buf + streambuf_fifo.wptr, n, L);

		fifo_wptr_incby(&streambuf_fifo, n);

		streambuf_bytes_received += n;
	}

	fifo_unlock(&streambuf_fifo);
	return n;
}
コード例 #20
0
ファイル: streambuf.c プロジェクト: gnalbandian/squeezeplay
/* returns true if the stream is still open but cannot yet supply the requested bytes */
bool_t streambuf_would_wait_for(size_t bytes) {
	size_t n;
	
	if (!streambuf_streaming) {
		return FALSE;
	}

	fifo_lock(&streambuf_fifo);

	n = fifo_bytes_used(&streambuf_fifo);

	fifo_unlock(&streambuf_fifo);

	return n < bytes;
}
コード例 #21
0
ファイル: serial.c プロジェクト: Ant1r/Fraise
int serial_pop_fifo(unsigned char* c)
{
  int res = -1;

  fifo_lock(&gfifo);

  if (gfifo.size)
    {
      *c = fifo_pop(&gfifo);
      res = 0;
    }

  fifo_unlock(&gfifo);

  return res;
}
コード例 #22
0
ファイル: streambuf.c プロジェクト: gnalbandian/squeezeplay
static int stream_icy_metaintervalL(lua_State *L) {
	/*
	 * 1: Stream (self)
	 * 2: meta interval
	 */

	fifo_lock(&streambuf_fifo);

	streambuf_filter = streambuf_icy_filter;

	icy_meta_interval = lua_tointeger(L, 2);
	icy_meta_remaining = icy_meta_interval;

	fifo_unlock(&streambuf_fifo);

	return 0;
}
コード例 #23
0
ファイル: meta_fifo.c プロジェクト: bjornaugestad/highlander
static void *reader(void *arg)
{
    fifo f = arg;

    while (fifo_wait_cond(f)) {
        char *s;

        while ((s = fifo_get(f)) != NULL) {
            fprintf(stderr, "From reader, who read: %s\n", s);
            free(s);
        }

        if (!fifo_unlock(f))
            break;
    }

    fprintf(stderr, "Exiting %s...\n", __func__);
    return NULL;
}
コード例 #24
0
ファイル: fifo.c プロジェクト: Themaister/libmaru
maru_error maru_fifo_set_read_trigger(maru_fifo *fifo, size_t size)
{
   maru_error ret = LIBMARU_SUCCESS;
   fifo_lock(fifo);

   if (size == 0)
      size = 1;

   if (size + fifo->write_trigger >= fifo->buffer_size)
   {
      ret = LIBMARU_ERROR_INVALID;
      goto end;
   }

   fifo->read_trigger = size;

end:
   fifo_unlock(fifo);
   return ret;
}
コード例 #25
0
ファイル: streambuf.c プロジェクト: gnalbandian/squeezeplay
size_t streambuf_read(u8_t *buf, size_t min, size_t max, bool_t *streaming) {
	ssize_t n;

	fifo_lock(&streambuf_fifo);

	if (streambuf_filter) {
		/* filters are called with the streambuf locked */
		n = streambuf_filter(buf, min, max, streaming);

		if (n < 0) {
			/* filter returned an error */
			current_decoder_state |= DECODE_STATE_ERROR;
			n = 0;
		}
	}
	else {
		n = streambuf_fast_read(buf, min, max, streaming);
	}

	fifo_unlock(&streambuf_fifo);

	return n;
}
コード例 #26
0
ファイル: streambuf.c プロジェクト: gnalbandian/squeezeplay
void streambuf_filter_unlock(void)
{
	fifo_unlock(&streambuf_fifo);
}
コード例 #27
0
ファイル: streambuf.c プロジェクト: gnalbandian/squeezeplay
static int stream_connectL(lua_State *L) {

	/*
	 * 1: self
	 * 2: server_ip
	 * 3: server_port
	 */

	struct sockaddr_in serv_addr;
	struct stream *stream;
	int flags;
	int err;
	socket_t fd;

	/* Server address and port */
	memset(&serv_addr, 0, sizeof(serv_addr));
	if (lua_type(L, 2) == LUA_TSTRING) {
		serv_addr.sin_addr.s_addr = inet_addr(luaL_checkstring(L, 2));
	}
	else {
		serv_addr.sin_addr.s_addr = htonl(luaL_checkinteger(L, 2));
	}
	serv_addr.sin_port = htons(luaL_checkinteger(L, 3));
	serv_addr.sin_family = AF_INET;


	LOG_DEBUG(log_audio_decode, "streambuf connect %s:%d", inet_ntoa(serv_addr.sin_addr), ntohs(serv_addr.sin_port));

	/* Create socket */
	fd = socket(AF_INET, SOCK_STREAM, 0);
	if (fd == INVALID_SOCKET) {
		lua_pushnil(L);
		lua_pushstring(L, strerror(SOCKETERROR));
		return 2;
	}

	/* Make socket non-blocking */
#if defined(WIN32)
	{
		u_long iMode = 0;
		flags = ioctlsocket(fd, FIONBIO, &iMode);
	}
#else
	flags = fcntl(fd, F_GETFL, 0);
	flags |= O_NONBLOCK;
	fcntl(fd, F_SETFL, flags);
#endif

	/* Connect socket */
	err = connect(fd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
	if (err != 0
#if !defined(WIN32)
		&&  SOCKETERROR != EINPROGRESS
#endif
		) {
		CLOSESOCKET(fd);

		lua_pushnil(L);
		lua_pushstring(L, strerror(SOCKETERROR));
		return 2;
	}

	/* Stream object */
	stream = lua_newuserdata(L, sizeof(struct stream));

	memset(stream, 0, sizeof(*stream));
	stream->fd = fd;

	luaL_getmetatable(L, "squeezeplay.stream");
	lua_setmetatable(L, -2);

	fifo_lock(&streambuf_fifo);

	streambuf_loop = FALSE;
	streambuf_bytes_received = 0;
	streambuf_copyright = FALSE;
	streambuf_filter = streambuf_next_filter;
	streambuf_next_filter = NULL;

	fifo_unlock(&streambuf_fifo);

	return 1;
}