Handles all procedures releated to messages of a group device.
More...
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/semaphore.h>
#include <linux/proc_fs.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
#include <linux/atomic.h>
#include "types.h"
Go to the source code of this file.
|
#define | NO_MSG_PRESENT 0 |
|
#define | ALLOC_ERR -2 |
|
#define | USER_COPY_ERR -3 |
|
#define | SEM_INIT_ERR -4 /** @brief Semaphore initialization **/ |
|
#define | MSG_INVALID_FORMAT -11 |
|
#define | MSG_SIZE_ERROR -12 |
|
#define | MEMORY_ERROR -13 |
|
#define | STORAGE_SIZE_ERR -14 |
|
#define | ALLOC_ERR -2 |
|
#define | CLASS_EXISTS -10 |
|
#define | CLASS_ERR -11 |
|
#define | DEV_CREATION_ERR -12 |
|
#define | CDEV_ALLOC_ERR -13 |
|
#define | EMPTY_LIST -20 |
|
#define | NODE_NOT_FOUND -21 |
|
#define | INVALID_IOCTL_COMMAND -1 |
|
#define | CHDEV_ALLOC_ERR -22 |
|
#define | DEFAULT_GC_RATIO 3 |
|
|
msg_manager_t * | createMessageManager (const u_int _max_storage_size, const u_int _max_message_size, garbage_collector_t *garbageCollector) |
| Allocate and initialize all the members of a 'msg_manager_t' struct. More...
|
|
int | writeMessage (msg_t *message, msg_manager_t *manager) |
| write message on a group queue More...
|
|
int | readMessage (msg_t *dest_buffer, msg_manager_t *manager) |
| Read a message from the corresponding queue. More...
|
|
int | copy_msg_from_user (msg_t *kmsg, const char *umsg, const ssize_t _size) |
| copy a msg_t structure from user-space to kernel-space More...
|
|
int | copy_msg_to_user (const msg_t *kmsg, __user char *ubuffer, const ssize_t _size) |
| copy a msg_t structure from kernel-space to user-space More...
|
|
void | queueGarbageCollector (struct work_struct *work) |
| Remove a message from the queue when it was completely delivered. More...
|
|
bool | isDelaySet (const msg_manager_t *manager) |
| Check if the message delay is greater than zero on a group. More...
|
|
void | delayedMessageCallback (struct timer_list *timer) |
| Called when a timer for a delayed message expires. More...
|
|
int | queueDelayedMessage (msg_t *message, msg_manager_t *manager) |
| Insert a delayed message into the pending queue. More...
|
|
int | revokeDelayedMessage (msg_manager_t *manager) |
| Remove all the delayed message from the queue. More...
|
|
int | cancelDelay (msg_manager_t *manager) |
| Set the delay of messages in the delay queue to zero. More...
|
|
Handles all procedures releated to messages of a group device.
◆ cancelDelay()
int cancelDelay |
( |
msg_manager_t * |
manager | ) |
|
Set the delay of messages in the delay queue to zero.
- Parameters
-
[in] | manager | The group's message manager |
- Returns
- The number of messages which delay was cancelled
- Note
- At the moment the function locks the delayed queue, set all timers to zero and unlock the queue. This means that while the function loops through the queue, timer's callback will wait since the queue is locked.
◆ copy_msg_from_user()
int copy_msg_from_user |
( |
msg_t * |
kmsg, |
|
|
const char * |
umsg, |
|
|
const ssize_t |
_size |
|
) |
| |
copy a msg_t structure from user-space to kernel-space
- Parameters
-
[out] | kmsg | Kernel-space msg_t |
[in] | umsg | User-space msg_t |
- Return values
-
0 | on success |
-EFAULT | if the copy fails |
- Todo:
- Check thread-safety of the function
- Note
- The kmsg structure must be allocated
◆ copy_msg_to_user()
int copy_msg_to_user |
( |
const msg_t * |
kmsg, |
|
|
__user char * |
ubuffer, |
|
|
const ssize_t |
_size |
|
) |
| |
copy a msg_t structure from kernel-space to user-space
- Parameters
-
[in] | kmsg | Kernel-space msg_t |
[out] | umsg | User-space buffer |
- Return values
-
0 | on success |
-EFAULT | if the copy fails |
- Todo:
- Check thread-safety of the function
- Note
- The umsg structure must be allocated
◆ createMessageManager()
msg_manager_t* createMessageManager |
( |
const u_int |
_max_storage_size, |
|
|
const u_int |
_max_message_size, |
|
|
garbage_collector_t * |
garbage_collector |
|
) |
| |
Allocate and initialize all the members of a 'msg_manager_t' struct.
- Parameters
-
[in] | _max_message_size | Configurable param |
[in] | _max_storage_size | Configurable param |
[in] | garbageCollectorFunction | Pointer to the work_struct responsible for garbage collection |
- Return values
-
An | 'msg_manager_t' pointer to an allocated an initialized 'msg_manager_t' struct |
A | NULL pointer in case the 'kmalloc' fails |
◆ delayedMessageCallback()
void delayedMessageCallback |
( |
struct timer_list * |
timer | ) |
|
Called when a timer for a delayed message expires.
The function simply take the existing 't_message_delayed_deliver' structure, extract the 'msg_t' field and write it into the FIFO queue via the 'writeMessage' function.
- Parameters
-
[in] | timer | The timer that elasped |
- Returns
- nothing
◆ isDelaySet()
bool isDelaySet |
( |
const msg_manager_t * |
manager | ) |
|
Check if the message delay is greater than zero on a group.
- Parameters
-
[in] | manager | A pointer to the message manager of the group |
- Note
- This function is thread-safe
- Return values
-
true | If the delay is greater than zero |
false | If the delay is zero |
◆ queueDelayedMessage()
int queueDelayedMessage |
( |
msg_t * |
message, |
|
|
msg_manager_t * |
manager |
|
) |
| |
Insert a delayed message into the pending queue.
- Parameters
-
[in] | message | The message to insert into the queue |
[in] | manager | A pointer to the current msg_manager_t of the group |
- Return values
-
◆ queueGarbageCollector()
void queueGarbageCollector |
( |
struct work_struct * |
work | ) |
|
Remove a message from the queue when it was completely delivered.
- Parameters
-
[in] | work | The work struct contained inside "msg_manager_t" |
- Returns
- nothing
- Todo:
- Check if size calculation are done correctly
- Note
- This function has three critical section, therefore it could be a bottleneck of the module
◆ readMessage()
int readMessage |
( |
msg_t * |
dest_buffer, |
|
|
msg_manager_t * |
manager |
|
) |
| |
Read a message from the corresponding queue.
- Return values
-
0 | on success |
1 | if no message is present |
-1 | on critical error |
This should't be necessary since the message's sender is automatically added in the list of recipients and, consequently, the 'wasDelivered' function should skip it. However for unknown reason this does not always happens (especially if the message is delayed)
- Bug:
- : when 'revoke delay' functionality is called, messages trigger this if and will not be delivered
◆ revokeDelayedMessage()
int revokeDelayedMessage |
( |
msg_manager_t * |
manager | ) |
|
Remove all the delayed message from the queue.
- Parameters
-
[in] | manager | The message manager of the group |
- Note
- This function is thread safe with respect to the list of delayed message
- Returns
- The number of delayed messages which revoked
◆ writeMessage()
int writeMessage |
( |
msg_t * |
message, |
|
|
msg_manager_t * |
manager |
|
) |
| |
write message on a group queue
- Parameters
-
[in] | message | The data pointed must never be deallocatated |
[in] | manager | Pointer to the message manager |
[in] | recipients | The head of the linked list containing the thread recipients |
- Return values
-
0 | on success |
STORAGE_SIZE_ERR | if the message does not respect the group's size limits |
ALLOC_ERR | if some allocation fails |
- Note
- Must be protected by a write-spinlock to avoid concurrent modification of The recipient data-structure and manager's message queue