/** * mds — A micro-display server * Copyright © 2014 Mattias Andrée (maandree@member.fsf.org) * * 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 3 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, see . */ #ifndef MDS_MDS_REGISTRY_SLAVE_H #define MDS_MDS_REGISTRY_SLAVE_H #include #include #include #include #include #include #define SLAVE_T_VERSION 0 /** * Slave information, a thread waiting for protocols to become available */ typedef struct slave { /** * Set of protocols for which to wait that they become available */ hash_table_t* wait_set; /** * The ID of the waiting client */ uint64_t client; /** * The ID of the waiting client */ char* client_id; /** * The ID of the message that triggered the waiting */ char* message_id; /** * The slave's node in the linked list of slaves */ ssize_t node; /** * Whether the client has been closed */ volatile sig_atomic_t closed; /** * The slave thread */ pthread_t thread; /** * The time slave should die if its condition * has not be meet at that time */ struct timespec dethklok; /** * Whether `dethklok` should apply */ int timed; } slave_t; /** * Start a slave thread * * @param wait_set Set of protocols for which to wait that they become available * @param recv_client_id The ID of the waiting client * @param recv_message_id The ID of the message that triggered the waiting * @return Non-zero on error */ int start_slave(hash_table_t* restrict wait_set, const char* restrict recv_client_id, const char* restrict recv_message_id); /** * Start a slave thread with an already created slave * * @param slave The slave * @return Non-zero on error, `errno` will be set accordingly */ int start_created_slave(slave_t* restrict slave); /** * Close all slaves associated with a client * * @param client The client's ID */ void close_slaves(uint64_t client); /** * Notify slaves that a protocol has become available * * @param command The protocol * @return Non-zero on error, `ernno`will be set accordingly */ int advance_slaves(char* command); /** * Create a slave * * @return The slave */ slave_t* slave_create(hash_table_t* restrict wait_set, const char* restrict recv_client_id, const char* restrict recv_message_id); /** * Initialise a slave * * @param this Memory slot in which to store the new slave information */ void slave_initialise(slave_t* restrict this); /** * Release all resources assoicated with a slave * * @param this The slave information */ void slave_destroy(slave_t* restrict this); /** * Calculate the buffer size need to marshal slave information * * @param this The slave information * @return The number of bytes to allocate to the output buffer */ size_t slave_marshal_size(const slave_t* restrict this) __attribute__((pure)); /** * Marshals slave information * * @param this The slave information * @param data Output buffer for the marshalled data * @return The number of bytes that have been written (everything will be written) */ size_t slave_marshal(const slave_t* restrict this, char* restrict data); /** * Unmarshals slave information * * @param this Memory slot in which to store the new slave information * @param data In buffer with the marshalled data * @return Zero on error, errno will be set accordingly, otherwise the number of read bytes. * Destroy the slave information on error. */ size_t slave_unmarshal(slave_t* restrict this, char* restrict data); /** * Pretend to unmarshal slave information * * @param data In buffer with the marshalled data * @return The number of read bytes */ size_t slave_unmarshal_skip(char* restrict data) __attribute__((pure)); #endif