/* SPDX-License-Identifier: BSD-2-Clause */ /** * @file * * @ingroup RTEMSMedia * * @brief Media implementation. */ /* * Copyright (C) 2009, 2010 embedded brains GmbH & Co. KG * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #define EVENT RTEMS_EVENT_13 typedef struct { rtems_chain_node node; rtems_media_event event; const char *src; rtems_media_worker worker; void *worker_arg; } message; static RTEMS_CHAIN_DEFINE_EMPTY(message_chain); static rtems_id server_id = RTEMS_ID_NONE; static void media_server(rtems_task_argument arg RTEMS_UNUSED) { rtems_status_code sc = RTEMS_SUCCESSFUL; while (true) { message *msg = NULL; sc = rtems_chain_get_with_wait( &message_chain, EVENT, RTEMS_NO_TIMEOUT, (rtems_chain_node **) &msg ); assert(sc == RTEMS_SUCCESSFUL); assert(msg != NULL); rtems_media_post_event( msg->event, msg->src, NULL, msg->worker, msg->worker_arg ); free(msg); } } rtems_status_code rtems_media_server_initialize( rtems_task_priority priority, size_t stack_size, rtems_mode modes, rtems_attribute attributes ) { rtems_status_code sc = RTEMS_SUCCESSFUL; if (server_id == RTEMS_ID_NONE) { sc = rtems_media_initialize(); if (sc != RTEMS_SUCCESSFUL) { goto error; } sc = rtems_task_create( rtems_build_name('M', 'D', 'I', 'A'), priority, stack_size, modes, attributes, &server_id ); if (sc != RTEMS_SUCCESSFUL) { goto error; } sc = rtems_task_start(server_id, media_server, 0); if (sc != RTEMS_SUCCESSFUL) { goto error; } } return RTEMS_SUCCESSFUL; error: if (server_id != RTEMS_ID_NONE) { rtems_task_delete(server_id); } return RTEMS_NO_MEMORY; } rtems_status_code rtems_media_server_post_event( rtems_media_event event, const char *src, rtems_media_worker worker, void *worker_arg ) { rtems_status_code sc = RTEMS_SUCCESSFUL; size_t src_size = strlen(src) + 1; message *msg = malloc(sizeof(*msg) + src_size); if (msg != NULL) { char *s = (char *) msg + sizeof(*msg); memcpy(s, src, src_size); msg->event = event; msg->src = s; msg->worker = worker; msg->worker_arg = worker_arg; rtems_chain_initialize_node(&msg->node); sc = rtems_chain_append_with_notification( &message_chain, &msg->node, server_id, EVENT ); if (sc != RTEMS_SUCCESSFUL) { sc = RTEMS_NOT_CONFIGURED; } } else { sc = RTEMS_NO_MEMORY; } return sc; }