Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- #include <errno.h>
- #include <pthread.h>
- #include <unistd.h>
- #include <string.h>
- // number of threads, for monitoring actions.
- #define NTHREAD 3
- // path, where to store files, with result of action# work
- const char path[] = "/home/zythar";
- // main working structure
- /*
- kinda dummy. in real program this is replaced with real functions.
- */
- struct server_t {
- char *name;
- int (*triggered)(struct server_t *); // event, thar is monitored
- int (*action)(struct server_t *); // action taken, when event triggered
- };
- typedef struct server_t server_t;
- /* structs for threads */
- typedef struct act_threads {
- pthread_t tid;
- char *servername;
- } act_threads_t;
- typedef struct act_checker {
- act_threads_t **actions;
- int count;
- } act_checker_t;
- /* structs for threads */ //END
- // function that is called, when action completed. it takes value, that action func returned, and write it to file named thread_#thread_id#
- int return_thread(pthread_t tid, int retval)
- {
- FILE *thread;
- char *fullpath;
- fullpath = (char *) malloc((strlen(path) + strlen("thread_") + 12) * sizeof(char));
- snprintf(fullpath, strlen(path) + strlen("thread_") + 12, "%s/thread_%lu", path, tid);
- thread = fopen(fullpath, "w");
- if (thread != NULL) {
- printf("%s created successfully\n", fullpath);
- fprintf(thread, "%d", retval);
- fclose(thread);
- } else {
- printf("Cannot create file for thread #%lu.\n", tid);
- printf("Exiting...\n");
- exit(0);
- }
- free(fullpath);
- return 0;
- }
- /* dummy funcs for events and actions */
- int triggered1(struct server_t * server)
- {
- if (time(NULL) % 5 == 0) {
- return 0;
- } else {
- return -1;
- }
- }
- int triggered2(struct server_t * server)
- {
- if (time(NULL) % 13 == 0) {
- return 0;
- } else {
- return -1;
- }
- }
- int triggered3(struct server_t * server)
- {
- if (time(NULL) % 17 == 0) {
- return 0;
- } else {
- return -1;
- }
- }
- int action1(struct server_t * server)
- {
- static int called_times;
- called_times = ( called_times > 0) ? called_times : 0;
- called_times++;
- int i = 0;
- while (i < 17) {
- i++;
- sleep(1);
- }
- return_thread(pthread_self(), 0);
- pthread_exit(NULL);
- return 0;
- }
- int action2(struct server_t * server)
- {
- static int called_times;
- called_times = ( called_times > 0) ? called_times : 0;
- called_times++;
- int i = 0;
- while (i < 41) {
- i++;
- sleep(1);
- }
- return_thread(pthread_self(), 0);
- pthread_exit(NULL);
- return 0;
- }
- int action3(struct server_t * server)
- {
- static int called_times;
- called_times = ( called_times > 0) ? called_times : 0;
- called_times++;
- int i = 0;
- while (i < 10) {
- i++;
- sleep(1);
- }
- return_thread(pthread_self(), 0);
- pthread_exit(NULL);
- return 0;
- }
- /* dummy funcs for events and actions */ //END
- /*int print_struct(act_checker_t *checker)
- {
- if (checker->count <= 0)
- return -1;
- int i;
- for (i = 0; i < checker->count; i++)
- printf("\t%d-th element. tid -- %lu\n", i, checker->actions[i]->tid);
- printf("\n\n");
- return 1;
- }*/
- // mutex, that is locked, when trying to modify struct checker
- pthread_mutex_t checker_mutex;
- // func, that checks if actions are completed, and if they are free space allocated for particular action
- void * check_threads(act_checker_t *checker)
- {
- printf("\n\n\t\tin %s\n\n", __FUNCTION__);
- FILE *thread;
- char *fullpath;
- int i; int status; int mut;
- fullpath = (char *) malloc((strlen(path) + strlen("thread_") + 12) * sizeof(char)); // path, where files are stored
- while (1) {
- // trying to lock mutex for modifying @checker. if not succeded try again, until lock is successfull.
- while (1) {
- mut = pthread_mutex_trylock (&checker_mutex);
- if (mut == 0 || mut == EDEADLK) { //if okay, or we own the lock then continue
- break;
- } else {
- sleep(3);
- }
- }
- // if no elements, then nothing to do. free mutex for others.
- if (checker->count <= 0) {
- pthread_mutex_unlock (&checker_mutex);
- continue;
- }
- // there are elements. check if threads completed, and if they are delete files and free alocated space for that thread
- for (i = 0; i < checker->count; i++) {
- snprintf(fullpath, strlen(path) + strlen("thread_") + 12, "%s/thread_%lu", path, checker->actions[i]->tid);
- thread = fopen(fullpath, "r");
- if (thread == NULL) { // if no such file, then thread not completed. continue to another thread.
- continue;
- } else {
- fscanf(thread, "%d", &status); // thread completed. read returned value and...
- fclose(thread);
- if (remove(fullpath) == 0) { // delete file.
- printf("%s removed successfully\n", fullpath);
- } else {
- printf("Cannot remove file for thread #%lu.\n", checker->actions[i]->tid);
- printf("Exiting...\n");
- exit(0);
- }
- free(checker->actions[i]); --checker->count; // free alocated memory for that thread.
- }
- }
- pthread_mutex_unlock (&checker_mutex);
- sleep(1);
- }
- free(fullpath);
- }
- // func, for creating thread for concrete action.
- void create_action_thread(act_checker_t *checker, server_t *server)
- {
- int actret; int mut;
- printf("\n\n\t\tin %s\n\n", __FUNCTION__);
- // locking mutex, because trying to modify @checker. until mutex locked don't do anything.
- while (1) {
- mut = pthread_mutex_trylock (&checker_mutex);
- if (mut == 0 || mut == EDEADLK) {
- break;
- } else {
- sleep(3);
- }
- }
- // if successfull, then alocating memory for that thread, creating the thread and unlocking mutex.
- ++checker->count;
- checker->actions = (act_threads_t **) realloc(checker->actions, checker->count * sizeof(act_threads_t *));
- checker->actions[checker->count-1] = (act_threads_t *) malloc(sizeof(act_threads_t ));
- checker->actions[checker->count-1]->servername = (char *) malloc((strlen(server->name) + 2) * sizeof(char));
- strncpy(checker->actions[checker->count-1]->servername, server->name, strlen(server->name) + 2);
- actret = pthread_create(&(checker->actions[checker->count-1]->tid), NULL, server->action, (void *) server);
- pthread_mutex_unlock (&checker_mutex);
- }
- int main()
- {
- /* initialization */
- printf("Initing mutex...");
- int init_ret;
- init_ret = pthread_mutex_init(&checker_mutex, NULL);
- if (init_ret != 0) {
- printf("pthread_mutex_init return %d. exiting...", init_ret);
- exit(0);
- } else {
- printf("Seems ok. %d returned\n", init_ret);
- }
- pthread_t threads[NTHREAD];
- pthread_t action_check;
- act_checker_t checker;
- checker.actions = NULL;
- checker.count = 0;
- int iret;
- int action_ret;
- long i; int ret = 1;
- server_t servers[] = {
- {"server1", triggered1, action1},
- {"server2", triggered2, action2},
- {"server3", triggered3, action2},
- };
- /* initialization */ // END
- // creating separate thread, to monitor file system.
- action_ret = pthread_create(&action_check, NULL, check_threads, (void *) &checker);
- /* create independent threads each of which will execute function */
- while (1) {
- for (i = 0; i < NTHREAD; i++) {
- iret = pthread_create(&threads[i], NULL, servers[i].triggered, (void *) &servers[i]);
- }
- for (i = 0; i < NTHREAD; i++) {
- pthread_join(threads[i], (void *) &ret);
- if (ret == 0) { // if any event triggered then...
- // creating thread for action of that event.
- create_action_thread(&checker, &servers[i]);
- }
- }
- sleep(1);
- }
- pthread_mutex_destroy(&checker_mutex);
- pthread_exit(NULL);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement