project for a (works on my devices) demo
This commit is contained in:
140
my_device_handler.c
Normal file
140
my_device_handler.c
Normal file
@@ -0,0 +1,140 @@
|
||||
#include "registries_items.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
#include "registries.h"
|
||||
#include "my_device_handler.h"
|
||||
|
||||
void reinitialize_all_devices_wrote_barrier( int childCount){
|
||||
int anyerror = pthread_barrier_init( &all_devices_wrote_barrier, NULL, 1 + childCount);
|
||||
if(anyerror){
|
||||
fprintf( stderr, "all_devices_wrote_barrier reinitialization error\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void reinitialize_devices_write_new_round_barrier( int childCount){
|
||||
int anyerror = pthread_barrier_init( &devices_write_new_round_barrier, NULL, 1 + childCount);
|
||||
if(anyerror){
|
||||
fprintf( stderr, "devices_write_new_round_barrier reinitialization error\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
int device_handler_init(){
|
||||
global_queue_init();
|
||||
reinitialize_all_devices_wrote_barrier(0);
|
||||
reinitialize_devices_write_new_round_barrier(0);
|
||||
initialize_device_added_flag_barrier();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int device_handler_add( const char *path){
|
||||
if( is_listed_as_active( path)){ /* already enlisted */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( is_listed_for_insertion( path)){ /* already requested the insertion */
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( is_listed_for_removal( path)){ /* undo the removal request */
|
||||
remove_from_update_list( path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
add_to_update_list( path, INSERT); /* request insertion */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int device_handler_remove( const char *path){
|
||||
printf("go with remove device\n");
|
||||
if( is_listed_for_removal( path)){ /* already requested the removal */
|
||||
printf("-> was alredy listed for removal\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( is_listed_for_insertion( path)){ /* undo the insertion request */
|
||||
printf("-> was listed for insertion, remove request\n");
|
||||
remove_from_update_list( path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( ! is_listed_as_active( path)){ /* is not enlisted anywhere */
|
||||
printf("-> is not listed as active\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
printf("-> have to enlist for removal\n");
|
||||
add_to_update_list( path, REMOVE); /* request removal */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* each device thread
|
||||
takes the mutex, writes its events, releases
|
||||
then reaches the all_wrote barrier
|
||||
then reaches the new_round barrier
|
||||
|
||||
|
||||
the main thread instead
|
||||
reaches the all_wrote barrier, releasing it
|
||||
reads all the events (dispatching them in some way or another)
|
||||
gets the count of devices waiting to be added and the count of those waiting to be removed
|
||||
if there are pending additions and/or removals
|
||||
calculate newChildCount
|
||||
if newChildCount != current
|
||||
recreates the all_wrote barrier with a count of (1 [itself] + newChildCount )
|
||||
adds all the devices waiting to be added, same for removals
|
||||
( placed here for preventing actions from the device threads listed for removal )
|
||||
reaches the new_round barrier, releasing it
|
||||
if newChildCount != current
|
||||
recreates the new_round barrier with a count of (1 [itself] + newChildCount )
|
||||
( the device list update was here, but this could have caused the lock on the first barrier of some of the device theads listed for removal,
|
||||
it is unspecified how the barrier behaves upon the destruction of a waiting thread
|
||||
they could have also stored some new event, causing minor inconsistencies
|
||||
)
|
||||
*/
|
||||
|
||||
int device_handler_poll_events( device_event** events){
|
||||
int currentChildCount;
|
||||
int update_delta;
|
||||
int newChildCount;
|
||||
|
||||
int events_count;
|
||||
|
||||
currentChildCount = active_list_count();
|
||||
|
||||
pthread_barrier_wait( &all_devices_wrote_barrier);
|
||||
|
||||
/* remove events from queue */
|
||||
events_count = drain_events_into( events);
|
||||
|
||||
update_delta = update_list_get_delta();
|
||||
newChildCount = currentChildCount + update_delta;
|
||||
|
||||
if( newChildCount != currentChildCount){
|
||||
reinitialize_all_devices_wrote_barrier( newChildCount);
|
||||
}
|
||||
|
||||
/* here update the devices list */
|
||||
update_list_drain_into_active();
|
||||
|
||||
pthread_barrier_wait( &devices_write_new_round_barrier);
|
||||
|
||||
if( newChildCount != currentChildCount){
|
||||
reinitialize_devices_write_new_round_barrier( newChildCount);
|
||||
currentChildCount = newChildCount;
|
||||
}
|
||||
|
||||
/* return the number of events*/
|
||||
return events_count;
|
||||
}
|
||||
|
||||
|
||||
void device_handler_destroy_events( device_event *events){
|
||||
/* no need for items destruction (they are static objects) */
|
||||
free( events);
|
||||
}
|
||||
Reference in New Issue
Block a user