mirror of
https://gitlab.xiph.org/xiph/icecast-common.git
synced 2025-02-02 15:07:47 -05:00
Feature: Make all IO functions thread safe.
This commit is contained in:
parent
02e0375711
commit
efc054cc89
134
src/io.c
134
src/io.c
@ -19,14 +19,28 @@
|
||||
|
||||
struct igloo_io_tag {
|
||||
igloo_interface_base(io)
|
||||
|
||||
/* Mutex for igloo_ro_*(). */
|
||||
igloo_mutex_t lock;
|
||||
|
||||
int touched;
|
||||
#if defined(IGLOO_CTC_HAVE_SYS_SELECT_H) || defined(IGLOO_CTC_HAVE_POLL)
|
||||
int fd;
|
||||
#endif
|
||||
};
|
||||
|
||||
static void __free(igloo_ro_t self)
|
||||
{
|
||||
igloo_io_t *io = igloo_RO_TO_TYPE(self, igloo_io_t);
|
||||
|
||||
igloo_thread_mutex_lock(&(io->lock));
|
||||
igloo_thread_mutex_unlock(&(io->lock));
|
||||
igloo_thread_mutex_destroy(&(io->lock));
|
||||
igloo_interface_base_free(self);
|
||||
}
|
||||
|
||||
igloo_RO_PUBLIC_TYPE(igloo_io_t,
|
||||
igloo_RO_TYPEDECL_FREE(igloo_interface_base_free)
|
||||
igloo_RO_TYPEDECL_FREE(__free)
|
||||
);
|
||||
|
||||
|
||||
@ -36,6 +50,8 @@ igloo_io_t * igloo_io_new(const igloo_io_ifdesc_t *ifdesc, igloo_ro_t backend_ob
|
||||
if (!io)
|
||||
return NULL;
|
||||
|
||||
igloo_thread_mutex_create(&(io->lock));
|
||||
|
||||
io->touched = 1;
|
||||
|
||||
return io;
|
||||
@ -44,47 +60,59 @@ igloo_io_t * igloo_io_new(const igloo_io_ifdesc_t *ifdesc, igloo_ro_t backend_ob
|
||||
|
||||
ssize_t igloo_io_read(igloo_io_t *io, void *buffer, size_t len)
|
||||
{
|
||||
ssize_t ret = -1;
|
||||
|
||||
if (!io || !buffer)
|
||||
return -1;
|
||||
|
||||
if (!len)
|
||||
return 0;
|
||||
|
||||
igloo_thread_mutex_lock(&(io->lock));
|
||||
io->touched = 1;
|
||||
|
||||
if (io->ifdesc->read)
|
||||
return io->ifdesc->read(igloo_INTERFACE_BASIC_CALL(io), buffer, len);
|
||||
ret = io->ifdesc->read(igloo_INTERFACE_BASIC_CALL(io), buffer, len);
|
||||
igloo_thread_mutex_unlock(&(io->lock));
|
||||
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ssize_t igloo_io_write(igloo_io_t *io, const void *buffer, size_t len)
|
||||
{
|
||||
ssize_t ret = -1;
|
||||
|
||||
if (!io || !buffer)
|
||||
return -1;
|
||||
|
||||
if (!len)
|
||||
return 0;
|
||||
|
||||
igloo_thread_mutex_lock(&(io->lock));
|
||||
io->touched = 1;
|
||||
|
||||
if (io->ifdesc->write)
|
||||
return io->ifdesc->write(igloo_INTERFACE_BASIC_CALL(io), buffer, len);
|
||||
ret = io->ifdesc->write(igloo_INTERFACE_BASIC_CALL(io), buffer, len);
|
||||
igloo_thread_mutex_unlock(&(io->lock));
|
||||
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int igloo_io_flush(igloo_io_t *io, igloo_io_opflag_t flags)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if (!io)
|
||||
return -1;
|
||||
|
||||
igloo_thread_mutex_lock(&(io->lock));
|
||||
io->touched = 1;
|
||||
|
||||
if (io->ifdesc->flush)
|
||||
return io->ifdesc->flush(igloo_INTERFACE_BASIC_CALL(io), flags);
|
||||
ret = io->ifdesc->flush(igloo_INTERFACE_BASIC_CALL(io), flags);
|
||||
igloo_thread_mutex_unlock(&(io->lock));
|
||||
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int igloo_io_sync(igloo_io_t *io, igloo_io_opflag_t flags)
|
||||
@ -94,46 +122,59 @@ int igloo_io_sync(igloo_io_t *io, igloo_io_opflag_t flags)
|
||||
if (!io)
|
||||
return -1;
|
||||
|
||||
igloo_thread_mutex_lock(&(io->lock));
|
||||
if (io->ifdesc->flush)
|
||||
io->ifdesc->flush(igloo_INTERFACE_BASIC_CALL(io), flags);
|
||||
|
||||
if (io->ifdesc->sync) {
|
||||
ret = io->ifdesc->sync(igloo_INTERFACE_BASIC_CALL(io), flags);
|
||||
if (ret != 0)
|
||||
if (ret != 0) {
|
||||
igloo_thread_mutex_unlock(&(io->lock));
|
||||
return ret;
|
||||
}
|
||||
|
||||
io->touched = 0;
|
||||
|
||||
igloo_thread_mutex_unlock(&(io->lock));
|
||||
return ret;
|
||||
}
|
||||
igloo_thread_mutex_unlock(&(io->lock));
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int igloo_io_set_blockingmode(igloo_io_t *io, libigloo_io_blockingmode_t mode)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if (!io)
|
||||
return -1;
|
||||
|
||||
if (mode != igloo_IO_BLOCKINGMODE_NONE && mode != igloo_IO_BLOCKINGMODE_FULL)
|
||||
return -1;
|
||||
|
||||
igloo_thread_mutex_lock(&(io->lock));
|
||||
io->touched = 1;
|
||||
|
||||
if (io->ifdesc->set_blockingmode)
|
||||
return io->ifdesc->set_blockingmode(igloo_INTERFACE_BASIC_CALL(io), mode);
|
||||
ret = io->ifdesc->set_blockingmode(igloo_INTERFACE_BASIC_CALL(io), mode);
|
||||
igloo_thread_mutex_unlock(&(io->lock));
|
||||
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
libigloo_io_blockingmode_t igloo_io_get_blockingmode(igloo_io_t *io)
|
||||
{
|
||||
libigloo_io_blockingmode_t ret = igloo_IO_BLOCKINGMODE_ERROR;
|
||||
|
||||
if (!io)
|
||||
return igloo_IO_BLOCKINGMODE_ERROR;
|
||||
|
||||
igloo_thread_mutex_lock(&(io->lock));
|
||||
if (io->ifdesc->get_blockingmode)
|
||||
return io->ifdesc->get_blockingmode(igloo_INTERFACE_BASIC_CALL(io));
|
||||
ret = io->ifdesc->get_blockingmode(igloo_INTERFACE_BASIC_CALL(io));
|
||||
igloo_thread_mutex_unlock(&(io->lock));
|
||||
|
||||
return igloo_IO_BLOCKINGMODE_ERROR;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef IGLOO_CTC_HAVE_SYS_SELECT_H
|
||||
@ -144,15 +185,24 @@ int igloo_io_select_set(igloo_io_t *io, fd_set *set, int *maxfd, igloo_io_opflag
|
||||
if (!io || !set || !maxfd)
|
||||
return -1;
|
||||
|
||||
if (!io->ifdesc->get_fd_for_systemcall)
|
||||
igloo_thread_mutex_lock(&(io->lock));
|
||||
if (!io->ifdesc->get_fd_for_systemcall) {
|
||||
igloo_thread_mutex_unlock(&(io->lock));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (io->touched || !(flags & igloo_IO_OPFLAG_NOWRITE)) {
|
||||
igloo_thread_mutex_unlock(&(io->lock));
|
||||
ret = igloo_io_sync(io, igloo_IO_OPFLAG_DEFAULTS|(flags & igloo_IO_OPFLAG_NOWRITE));
|
||||
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
if (io->touched)
|
||||
|
||||
igloo_thread_mutex_lock(&(io->lock));
|
||||
if (io->touched) {
|
||||
igloo_thread_mutex_unlock(&(io->lock));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
io->fd = io->ifdesc->get_fd_for_systemcall(igloo_INTERFACE_BASIC_CALL(io));
|
||||
@ -163,6 +213,8 @@ int igloo_io_select_set(igloo_io_t *io, fd_set *set, int *maxfd, igloo_io_opflag
|
||||
if (*maxfd < io->fd)
|
||||
*maxfd = io->fd;
|
||||
|
||||
igloo_thread_mutex_unlock(&(io->lock));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -171,23 +223,31 @@ int igloo_io_select_clear(igloo_io_t *io, fd_set *set)
|
||||
if (!io || !set)
|
||||
return -1;
|
||||
|
||||
if (io->touched || io->fd < 0)
|
||||
igloo_thread_mutex_lock(&(io->lock));
|
||||
if (io->touched || io->fd < 0) {
|
||||
igloo_thread_mutex_unlock(&(io->lock));
|
||||
return -1;
|
||||
}
|
||||
|
||||
FD_CLR(io->fd, set);
|
||||
igloo_thread_mutex_unlock(&(io->lock));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int igloo_io_select_isset(igloo_io_t *io, fd_set *set)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if (!io || !set)
|
||||
return -1;
|
||||
|
||||
if (io->touched || io->fd < 0)
|
||||
return -1;
|
||||
igloo_thread_mutex_lock(&(io->lock));
|
||||
if (!io->touched && io->fd >= 0)
|
||||
ret = FD_ISSET(io->fd, set) ? 1 : 0;
|
||||
igloo_thread_mutex_unlock(&(io->lock));
|
||||
|
||||
return FD_ISSET(io->fd, set) ? 1 : 0;
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -208,27 +268,40 @@ int igloo_io_poll_fill(igloo_io_t *io, struct pollfd *fd, short events)
|
||||
if (!io || !fd)
|
||||
return -1;
|
||||
|
||||
if (!io->ifdesc->get_fd_for_systemcall)
|
||||
return -1;
|
||||
|
||||
is_safe = !((events|safe_events) - safe_events);
|
||||
|
||||
igloo_thread_mutex_lock(&(io->lock));
|
||||
if (!io->ifdesc->get_fd_for_systemcall) {
|
||||
igloo_thread_mutex_unlock(&(io->lock));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (io->touched || !is_safe) {
|
||||
igloo_thread_mutex_unlock(&(io->lock));
|
||||
ret = igloo_io_sync(io, igloo_IO_OPFLAG_DEFAULTS|(is_safe ? 0 : igloo_IO_OPFLAG_NOWRITE));
|
||||
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
if (io->touched)
|
||||
|
||||
igloo_thread_mutex_lock(&(io->lock));
|
||||
if (io->touched) {
|
||||
igloo_thread_mutex_unlock(&(io->lock));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
io->fd = io->ifdesc->get_fd_for_systemcall(igloo_INTERFACE_BASIC_CALL(io));
|
||||
if (io->fd < 0)
|
||||
if (io->fd < 0) {
|
||||
igloo_thread_mutex_unlock(&(io->lock));
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(fd, 0, sizeof(*fd));
|
||||
fd->fd = io->fd;
|
||||
fd->events = events;
|
||||
|
||||
igloo_thread_mutex_unlock(&(io->lock));
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@ -236,18 +309,19 @@ int igloo_io_poll_fill(igloo_io_t *io, struct pollfd *fd, short events)
|
||||
int igloo_io_control(igloo_io_t *io, igloo_io_opflag_t flags, igloo_io_control_t control, ...)
|
||||
{
|
||||
#ifdef IGLOO_CTC_STDC_HEADERS
|
||||
int ret;
|
||||
int ret = -1;
|
||||
va_list ap;
|
||||
|
||||
if (!io)
|
||||
return -1;
|
||||
|
||||
if (!io->ifdesc->control)
|
||||
return -1;
|
||||
|
||||
va_start(ap, control);
|
||||
ret = io->ifdesc->control(igloo_INTERFACE_BASIC_CALL(io), flags, control, ap);
|
||||
va_end(ap);
|
||||
igloo_thread_mutex_lock(&(io->lock));
|
||||
if (io->ifdesc->control) {
|
||||
va_start(ap, control);
|
||||
ret = io->ifdesc->control(igloo_INTERFACE_BASIC_CALL(io), flags, control, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
igloo_thread_mutex_unlock(&(io->lock));
|
||||
|
||||
return ret;
|
||||
#else
|
||||
|
Loading…
x
Reference in New Issue
Block a user