From db16efe68b13a60c0efdb5b02dd56dab7e5a43bc Mon Sep 17 00:00:00 2001 From: Quantum Date: Thu, 11 Feb 2021 04:01:52 -0500 Subject: [PATCH] [common] add a reference counted buffer type This allows buffers to be shared between different asynchronous operations. Once all users no longer need the buffer, it will be freed. The motivation for this is being able to stream Wayland clipboard data asynchronously to multiple clients. The buffer should only be freed after the clipboard has changed and all ongoing transfer completes. --- common/CMakeLists.txt | 1 + common/include/common/countedbuffer.h | 30 +++++++++++++++++ common/src/countedbuffer.c | 47 +++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 common/include/common/countedbuffer.h create mode 100644 common/src/countedbuffer.c diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index ff152a83..ea7bb73d 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -19,6 +19,7 @@ set(COMMON_SOURCES src/option.c src/framebuffer.c src/KVMFR.c + src/countedbuffer.c ) add_library(lg_common STATIC ${COMMON_SOURCES}) diff --git a/common/include/common/countedbuffer.h b/common/include/common/countedbuffer.h new file mode 100644 index 00000000..83ab1a94 --- /dev/null +++ b/common/include/common/countedbuffer.h @@ -0,0 +1,30 @@ +/* +Looking Glass - KVM FrameRelay (KVMFR) Client +Copyright (C) 2021 Guanzhong Chen +https://looking-glass.hostfission.com + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include + +struct CountedBuffer { + _Atomic(size_t) refs; + size_t size; + char data[]; +}; + +struct CountedBuffer * countedBufferNew(size_t size); +void countedBufferAddRef(struct CountedBuffer * buffer); +void countedBufferRelease(struct CountedBuffer ** buffer); diff --git a/common/src/countedbuffer.c b/common/src/countedbuffer.c new file mode 100644 index 00000000..4ac8b379 --- /dev/null +++ b/common/src/countedbuffer.c @@ -0,0 +1,47 @@ +/* +Looking Glass - KVM FrameRelay (KVMFR) Client +Copyright (C) 2021 Guanzhong Chen +https://looking-glass.hostfission.com + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "common/countedbuffer.h" +#include +#include + +struct CountedBuffer * countedBufferNew(size_t size) +{ + struct CountedBuffer * buffer = malloc(sizeof(struct CountedBuffer) + size); + if (!buffer) + return NULL; + + atomic_init(&buffer->refs, 1); + buffer->size = size; + return buffer; +} + +void countedBufferAddRef(struct CountedBuffer * buffer) +{ + atomic_fetch_add(&buffer->refs, 1); +} + +void countedBufferRelease(struct CountedBuffer ** buffer) +{ + if (atomic_fetch_sub(&(*buffer)->refs, 1) == 1) + { + free(*buffer); + *buffer = NULL; + } +}