| summaryrefslogtreecommitdiff | 
diff options
| author | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2017-01-31 16:21:24 +0100 | 
|---|---|---|
| committer | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2017-01-31 16:21:24 +0100 | 
| commit | 509ac16d892aeb5091f68620247f6815d2e4b5f5 (patch) | |
| tree | c4adebce7791c10c4c362b77f32d4a339e8c8125 | |
| parent | 1373211465c34015ee900e097aa87fbffb401187 (diff) | |
Switched to sockets, continuing implementation...
30 files changed, 1268 insertions, 315 deletions
diff --git a/src/knowledge/knowledge.c b/src/knowledge/knowledge.c index 463d40b..c9bfc2a 100644 --- a/src/knowledge/knowledge.c +++ b/src/knowledge/knowledge.c @@ -1,5 +1,6 @@  #include <stdlib.h>  #include <string.h> +#include <stdio.h>  #include <stdint.h> /* defines SIZE_MAX */  #include "../pipe/pipe.h" @@ -9,8 +10,10 @@  /** Basic functions of the ZoO_knowledge structure ****************************/  /* See: "knowledge.h" */ -void ZoO_knowledge_initialize (struct ZoO_knowledge k [const static 1]) +int ZoO_knowledge_initialize (struct ZoO_knowledge k [const restrict static 1])  { +   int error; +     k->words = (struct ZoO_knowledge_word *) NULL;     k->words_length = 0;     k->words_sorted = (ZoO_index *) NULL; @@ -18,6 +21,22 @@ void ZoO_knowledge_initialize (struct ZoO_knowledge k [const static 1])     k->sequences = (ZoO_index **) NULL;     k->sequences_length = 0;     k->sequences_sorted = (ZoO_index *) NULL; + +   error = pthread_mutex_init(&(k->mutex), (const pthread_mutexattr_t *) NULL); + +   if (error != 0) +   { +      fprintf +      ( +         stderr, +         "[F] Unable to initialize knowledge mutex: %s.\n", +         strerror(error) +      ); + +      return -1; +   } + +   return 0;  }  int ZoO_knowledge_lock_access @@ -26,8 +45,7 @@ int ZoO_knowledge_lock_access     const struct ZoO_pipe io [const restrict static 1]  )  { -   /* TODO */ -   return 0; +   return pthread_mutex_lock(&(k->mutex));  }  void ZoO_knowledge_unlock_access @@ -36,5 +54,5 @@ void ZoO_knowledge_unlock_access     const struct ZoO_pipe io [const restrict static 1]  )  { -   /* TODO */ +   pthread_mutex_unlock(&(k->mutex));  } diff --git a/src/knowledge/knowledge.h b/src/knowledge/knowledge.h index c65ee2c..e868943 100644 --- a/src/knowledge/knowledge.h +++ b/src/knowledge/knowledge.h @@ -20,10 +20,7 @@ void ZoO_knowledge_unlock_access     const struct ZoO_pipe io [const restrict static 1]  ); -void ZoO_knowledge_initialize -( -   struct ZoO_knowledge k [const restrict static 1] -); +int ZoO_knowledge_initialize (struct ZoO_knowledge k [const restrict static 1]);  void ZoO_knowledge_finalize (struct ZoO_knowledge k [const restrict static 1]); @@ -59,13 +56,12 @@ int ZoO_knowledge_learn_markov_sequence  (     struct ZoO_knowledge k [const restrict static 1],     const ZoO_index sequence [const restrict static 1], -   const ZoO_index sequence_length, -   const ZoO_index markov_order, +   const ZoO_index markov_order, /* Pre (> markov_order 1) */     ZoO_index sequence_id [const restrict static 1],     const struct ZoO_pipe io [const restrict static 1]  ); -int ZoO_knowledge_get_following_sequences_ref +int ZoO_knowledge_get_swt_sequences_ref  (     const struct ZoO_knowledge k [const static 1],     const ZoO_index initial_word, @@ -110,27 +106,67 @@ int ZoO_knowledge_find_word_id     ZoO_index result [const restrict static 1]  ); -int ZoO_knowledge_find_preceding_words +int ZoO_knowledge_find_tws_targets  (     const struct ZoO_knowledge k [const static 1],     const ZoO_index sequence [const restrict],     const ZoO_index markov_order, -   const ZoO_index * restrict preceding_words [const restrict static 1], -   const ZoO_index * restrict preceding_words_weights [const restrict static 1], -   ZoO_index preceding_words_weights_sum [const restrict static 1], +   const ZoO_index * restrict targets [const restrict static 1], +   const ZoO_index * restrict targets_weights [const restrict static 1], +   ZoO_index targets_weights_sum [const restrict static 1],     const struct ZoO_pipe io [const restrict static 1]  ); -int ZoO_knowledge_find_following_words +int ZoO_knowledge_find_swt_targets  (     const struct ZoO_knowledge k [const static 1],     const ZoO_index sequence [const restrict],     const size_t sequence_length,     const ZoO_index markov_order, -   const ZoO_index * restrict following_words [const restrict static 1], -   const ZoO_index * restrict following_words_weights [const restrict static 1], -   ZoO_index following_words_weights_sum [const restrict static 1], +   const ZoO_index * restrict targets [const restrict static 1], +   const ZoO_index * restrict targets_weights [const restrict static 1], +   ZoO_index targets_weights_sum [const restrict static 1], +   const struct ZoO_pipe io [const restrict static 1] +); + +int ZoO_knowledge_strengthen_swt +( +   struct ZoO_knowledge k [const restrict static 1], +   const ZoO_index sequence_id, +   const ZoO_index word_id, +   const ZoO_index target_id, +   const struct ZoO_pipe io [const restrict static 1] +); + +int ZoO_knowledge_strengthen_tws +( +   struct ZoO_knowledge k [const restrict static 1], +   const ZoO_index target_id, +   const ZoO_index word_id, +   const ZoO_index sequence_id,     const struct ZoO_pipe io [const restrict static 1]  ); +/* + * TODO + */ +/* +int ZoO_knowledge_weaken_swt +( +   struct ZoO_knowledge k [const restrict static 1], +   const ZoO_index sequence_id, +   const ZoO_index word_id, +   const ZoO_index target_id, +   const struct ZoO_pipe io [const restrict static 1] +); + +int ZoO_knowledge_weaken_tws +( +   struct ZoO_knowledge k [const restrict static 1], +   const ZoO_index target_id, +   const ZoO_index word_id, +   const ZoO_index sequence_id, +   const struct ZoO_pipe io [const restrict static 1] +); +*/  #endif diff --git a/src/knowledge/knowledge_finalize.c b/src/knowledge/knowledge_finalize.c index 9628672..9546650 100644 --- a/src/knowledge/knowledge_finalize.c +++ b/src/knowledge/knowledge_finalize.c @@ -65,8 +65,8 @@ static void knowledge_word_finalize        w->word = (ZoO_char *) NULL;     } -   knowledge_sequence_collection_finalize(&(w->followed)); -   knowledge_sequence_collection_finalize(&(w->preceded)); +   knowledge_sequence_collection_finalize(&(w->swt)); +   knowledge_sequence_collection_finalize(&(w->tws));  }  /* See: "knowledge.h" */ @@ -115,4 +115,6 @@ void ZoO_knowledge_finalize (struct ZoO_knowledge k [const restrict static 1])        k->sequences_sorted = (ZoO_index *) NULL;     } + +   pthread_mutex_destroy(&(k->mutex));  } diff --git a/src/knowledge/knowledge_learn_markov_sequence.c b/src/knowledge/knowledge_learn_markov_sequence.c index 2bd0103..4258c4a 100644 --- a/src/knowledge/knowledge_learn_markov_sequence.c +++ b/src/knowledge/knowledge_learn_markov_sequence.c @@ -143,7 +143,6 @@ static int reallocate_sequences_sorted_list  static ZoO_index * copy_sequence  (     const ZoO_index base [const restrict static 1], -   const ZoO_index base_length,     const ZoO_index destination_length,     const struct ZoO_pipe io [const restrict static 1]  ) @@ -169,45 +168,12 @@ static ZoO_index * copy_sequence        return (ZoO_index *) NULL;     } -   if (base_length == destination_length) -   { -      memcpy -      ( -         (void *) result, -         (const void *) base, -         (((size_t) base_length) * sizeof(ZoO_index)) -      ); -   } -   else if (base[0] == ZoO_START_OF_SEQUENCE_ID) -   { -      diff = (destination_length - base_length); - -      memcpy -      ( -         (void *) (result + diff), -         (const void *) base, -         (((size_t) base_length) * sizeof(ZoO_index)) -      ); - -      for (i = 0; i < diff; ++i) -      { -         result[i] = ZoO_START_OF_SEQUENCE_ID; -      } -   } -   else if (base[(base_length - 1)] == ZoO_END_OF_SEQUENCE_ID) -   { -      memcpy -      ( -         (void *) result, -         (const void *) base, -         (((size_t) base_length) * sizeof(ZoO_index)) -      ); - -      for (i = base_length; i < destination_length; ++i) -      { -         result[i] = ZoO_END_OF_SEQUENCE_ID; -      } -   } +   memcpy +   ( +      (void *) result, +      (const void *) base, +      (((size_t) destination_length) * sizeof(ZoO_index)) +   );     return result;  } @@ -220,7 +186,6 @@ static int add_sequence  (     struct ZoO_knowledge k [const restrict static 1],     const ZoO_index sequence [const restrict static 1], -   const ZoO_index sequence_length,     const ZoO_index markov_order, /* Pre (> markov_order 1) */     const ZoO_index sequence_id,     const ZoO_index sorted_sequence_id, @@ -241,7 +206,7 @@ static int add_sequence        return -1;     } -   stored_sequence = copy_sequence(sequence, sequence_length, markov_order, io); +   stored_sequence = copy_sequence(sequence, (markov_order - 1), io);     if (stored_sequence == (ZoO_index *) NULL)     { @@ -283,7 +248,6 @@ static int find_sequence  (     const struct ZoO_knowledge k [const static 1],     const ZoO_index sequence [const restrict static 1], -   const ZoO_index sequence_length,     const ZoO_index markov_order, /* Pre: (> 1) */     ZoO_index sequence_id [const restrict static 1]  ) @@ -317,7 +281,7 @@ static int find_sequence              k->sequences[k->sequences_sorted[i]],              markov_sequence_length,              sequence, -            sequence_length +            markov_sequence_length           );        if (cmp > 0) @@ -359,7 +323,6 @@ int ZoO_knowledge_learn_markov_sequence  (     struct ZoO_knowledge k [const restrict static 1],     const ZoO_index sequence [const restrict static 1], -   const ZoO_index sequence_length,     const ZoO_index markov_order, /* Pre (> markov_order 1) */     ZoO_index sequence_id [const restrict static 1],     const struct ZoO_pipe io [const restrict static 1] @@ -373,7 +336,6 @@ int ZoO_knowledge_learn_markov_sequence        (           k,           sequence, -         sequence_length,           markov_order,           sequence_id        ) == 0 @@ -390,7 +352,6 @@ int ZoO_knowledge_learn_markov_sequence        (           k,           sequence, -         sequence_length,           markov_order,           *sequence_id,           sorted_id, diff --git a/src/knowledge/knowledge_learn_sequence.c b/src/knowledge/knowledge_learn_sequence.c index 35b6d15..927b186 100644 --- a/src/knowledge/knowledge_learn_sequence.c +++ b/src/knowledge/knowledge_learn_sequence.c @@ -8,38 +8,180 @@  #include "knowledge.h" + +  /******************************************************************************/  /** LEARN FOLLOWING SEQUENCE **************************************************/  /******************************************************************************/ -static int add_following_sequence +static void parse_swt_sequence +( +   const ZoO_index sequence [const restrict static 1], +   const size_t index, +   ZoO_index buffer [const restrict static 1], +   const ZoO_index buffer_length +) +{ +   size_t j; +   size_t index_offset; + +   index_offset = buffer_length; + +   for (j = 0; j < buffer_length; ++j) +   { +      index_offset = (buffer_length - j); + +      if (index >= index_offset) +      { +         buffer[j] = sequence[index - index_offset]; +      } +      else +      { +         buffer[j] = ZoO_START_OF_SEQUENCE_ID; +      } +   } +} + +static int add_swt_sequence  (     struct ZoO_knowledge k [const restrict static 1],     const ZoO_index sequence [const restrict static 1],     const size_t index,     const size_t sequence_length, -   const ZoO_index markov_order, +   ZoO_index buffer [const restrict static 1], +   const ZoO_index buffer_length,     const struct ZoO_pipe io [const restrict static 1]  )  { -   /* TODO */ -   return -1; +   ZoO_index sequence_id; + +   parse_swt_sequence(sequence, index, buffer, buffer_length); + +   if +   ( +      ZoO_knowledge_learn_markov_sequence +      ( +         k, +         buffer, +         (buffer_length + 1), +         &sequence_id, +         io +      ) +   ) +   { +      return -1; +   } + +   if (index == (sequence_length - 1)) +   { +      return +         ZoO_knowledge_strengthen_swt +         ( +            k, +            sequence_id, +            sequence[index], +            ZoO_END_OF_SEQUENCE_ID, +            io +         ); +   } +   else +   { +      return +         ZoO_knowledge_strengthen_swt +         ( +            k, +            sequence_id, +            sequence[index], +            sequence[index + 1], +            io +         ); +   }  }  /******************************************************************************/  /** LEARN PRECEDING SEQUENCE **************************************************/  /******************************************************************************/ -static int add_preceding_sequence +static void parse_tws_sequence +( +   const ZoO_index sequence [const restrict static 1], +   const size_t index, +   const size_t sequence_length, +   ZoO_index buffer [const restrict static 1], +   const ZoO_index buffer_length +) +{ +   size_t j; +   size_t index_offset; +   const size_t remaining_items = (sequence_length - index); + +   for (j = 0; j < buffer_length; ++j) +   { +      index_offset = (j + 1); + +      if (remaining_items > index_offset) +      { +         buffer[j] = sequence[index + index_offset]; +      } +      else +      { +         buffer[j] = ZoO_END_OF_SEQUENCE_ID; +      } +   } +} + +static int add_tws_sequence  (     struct ZoO_knowledge k [const restrict static 1],     const ZoO_index sequence [const restrict static 1],     const size_t index,     const size_t sequence_length, -   const ZoO_index markov_order, +   ZoO_index buffer [const restrict static 1], +   const ZoO_index buffer_length,     const struct ZoO_pipe io [const restrict static 1]  )  { -   /* TODO */ -   return -1; +   ZoO_index sequence_id; + +   parse_tws_sequence(sequence, index, sequence_length, buffer, buffer_length); + +   if +   ( +      ZoO_knowledge_learn_markov_sequence +      ( +         k, +         buffer, +         (buffer_length + 1), +         &sequence_id, +         io +      ) +   ) +   { +      return -1; +   } + +   if (index == 0) +   { +      return +         ZoO_knowledge_strengthen_tws +         ( +            k, +            ZoO_START_OF_SEQUENCE_ID, +            sequence[index], +            sequence_id, +            io +         ); +   } +   else +   { +      return +         ZoO_knowledge_strengthen_tws +         ( +            k, +            sequence[index - 1], +            sequence[index], +            sequence_id, +            io +         ); +   }  }  /******************************************************************************/ @@ -58,35 +200,49 @@ int ZoO_knowledge_learn_sequence     size_t i;     const ZoO_index buffer_length = (markov_order - 1); -   for (i = 0; i < sequence_length; ++i) +   buffer = +      (ZoO_index *) calloc +      ( +         (size_t) buffer_length, +         sizeof(ZoO_index) +      ); + +   if (buffer == (ZoO_index *) NULL)     { -      k->words[sequence[i]].occurrences += 1; +      ZoO_S_ERROR +      ( +         io, +         "Unable to allocate memory required to create markov sequences." +      ); + +      return -1; +   } -      add_preceding_sequence +   for (i = 0; i < sequence_length; ++i) +   { +      add_tws_sequence        (           k,           sequence,           i,           sequence_length, +         buffer,           buffer_length,           io        ); -      add_following_sequence +      add_swt_sequence        (           k,           sequence,           i,           sequence_length, -         markov_order, +         buffer, +         buffer_length,           io        ); -      /* -       * TODO: in case of failure, undo part of the word done so far: instead -       * of unlearning, just remove the occurrence count of sequences and -       * words so that {k} remains coherent. -       */ +      k->words[sequence[i]].occurrences += 1;     }     return 0; diff --git a/src/knowledge/knowledge_learn_word.c b/src/knowledge/knowledge_learn_word.c index 33a2bf1..5d932d2 100644 --- a/src/knowledge/knowledge_learn_word.c +++ b/src/knowledge/knowledge_learn_word.c @@ -33,8 +33,8 @@ static void initialize_word     w->word_length = 0;     w->occurrences = 0; -   initialize_sequence_collection(&(w->followed)); -   initialize_sequence_collection(&(w->preceded)); +   initialize_sequence_collection(&(w->swt)); +   initialize_sequence_collection(&(w->tws));  }  /******************************************************************************/ diff --git a/src/knowledge/knowledge_search.c b/src/knowledge/knowledge_search.c index 4ea4572..198da1d 100644 --- a/src/knowledge/knowledge_search.c +++ b/src/knowledge/knowledge_search.c @@ -73,14 +73,15 @@ int ZoO_knowledge_find_word_id     }  } -int ZoO_knowledge_find_preceding_words +/* pre: \length(sequence) >= markov_order */ +int ZoO_knowledge_find_tws_targets  (     const struct ZoO_knowledge k [const static 1], -   const ZoO_index sequence [const restrict], +   const ZoO_index sequence [restrict static 1],     const ZoO_index markov_order, /* Pre: (> 0) */ -   const ZoO_index * restrict preceding_words [const restrict static 1], -   const ZoO_index * restrict preceding_words_weights [const restrict static 1], -   ZoO_index preceding_words_weights_sum [const restrict static 1], +   const ZoO_index * restrict targets [const restrict static 1], +   const ZoO_index * restrict targets_weights [const restrict static 1], +   ZoO_index targets_weights_sum [const restrict static 1],     const struct ZoO_pipe io [const restrict static 1]  )  { @@ -89,19 +90,23 @@ int ZoO_knowledge_find_preceding_words     ZoO_index i, current_min, current_max, local_sequence;     const ZoO_index * restrict candidate;     const ZoO_index markov_sequence_length = (markov_order - 1); -   const ZoO_index word = sequence[markov_sequence_length]; +   const ZoO_index word = sequence[0]; -   if (word >= k->words_length) +   if +   ( +      (word >= k->words_length) +      || (k->words[word].occurrences == 0) +   )     {        ZoO_S_ERROR        (           io, -         "Attempting to find the preceding words of an unknown word." +         "Attempting to find the TWS targets of an unknown word."        ); -      *preceding_words = (const ZoO_index *) NULL; -      *preceding_words_weights = (const ZoO_index *) NULL; -      *preceding_words_weights_sum = 0; +      *targets = (const ZoO_index *) NULL; +      *targets_weights = (const ZoO_index *) NULL; +      *targets_weights_sum = 0;        return -1;     } @@ -110,30 +115,34 @@ int ZoO_knowledge_find_preceding_words     if (markov_order == 1)     {        /* Special case: empty sequences. */ -      *preceding_words = (const ZoO_index *) k->words[word].preceded.targets; +      *targets = (const ZoO_index *) k->words[word].tws.targets; -      *preceding_words_weights = -         (const ZoO_index *) k->words[word].preceded.targets_occurrences; +      *targets_weights = +         (const ZoO_index *) k->words[word].tws.targets_occurrences; -      *preceding_words_weights_sum = k->words[word].occurrences; +      *targets_weights_sum = k->words[word].occurrences;        return 0;     } + +   /* pre: \length(sequence) >= markov_order */ +   /* markov_order > 1 */ +   sequence += 1; /* get the relevant part of the sequence. */ +     /* Handles the case where the list is empty ********************************/ -   current_max = k->words[word].preceded.sequences_ref_length; +   current_max = k->words[word].tws.sequences_ref_length;     if (current_max == 0)     { -      *preceding_words = (const ZoO_index *) NULL; -      *preceding_words_weights = (const ZoO_index *) NULL; -      *preceding_words_weights_sum = 0; +      *targets = (const ZoO_index *) NULL; +      *targets_weights = (const ZoO_index *) NULL; +      *targets_weights_sum = 0;        ZoO_S_ERROR        (           io, -         "Attempting to find the preceding words of a sequence that never had " -         "any." +         "Attempting to find the TWS targets of a sequence that never had any."        );        return -2; @@ -147,12 +156,12 @@ int ZoO_knowledge_find_preceding_words     {        i = (current_min + ((current_max - current_min) / 2)); -      local_sequence = k->words[word].preceded.sequences_ref_sorted[i]; +      local_sequence = k->words[word].tws.sequences_ref_sorted[i];        (void) ZoO_knowledge_get_sequence        (           k, -         k->words[word].preceded.sequences_ref[local_sequence], +         k->words[word].tws.sequences_ref[local_sequence],           &candidate,           io        ); @@ -172,9 +181,9 @@ int ZoO_knowledge_find_preceding_words           if (current_min > current_max)           { -            *preceding_words = (const ZoO_index *) NULL; -            *preceding_words_weights = (const ZoO_index *) NULL; -            *preceding_words_weights_sum = 0; +            *targets = (const ZoO_index *) NULL; +            *targets_weights = (const ZoO_index *) NULL; +            *targets_weights_sum = 0;              return -2;           } @@ -183,9 +192,9 @@ int ZoO_knowledge_find_preceding_words        {           if ((current_min > current_max) || (i == 0))           { -            *preceding_words = (const ZoO_index *) NULL; -            *preceding_words_weights = (const ZoO_index *) NULL; -            *preceding_words_weights_sum = 0; +            *targets = (const ZoO_index *) NULL; +            *targets_weights = (const ZoO_index *) NULL; +            *targets_weights_sum = 0;              return -2;           } @@ -194,28 +203,28 @@ int ZoO_knowledge_find_preceding_words        }        else        { -         *preceding_words = k->words[word].preceded.targets[local_sequence]; +         *targets = k->words[word].tws.targets[local_sequence]; -         *preceding_words_weights = -            k->words[word].preceded.targets_occurrences[local_sequence]; +         *targets_weights = +            k->words[word].tws.targets_occurrences[local_sequence]; -         *preceding_words_weights_sum = -            k->words[word].preceded.occurrences[local_sequence]; +         *targets_weights_sum = +            k->words[word].tws.occurrences[local_sequence];           return 0;        }     }  } -int ZoO_knowledge_find_following_words +int ZoO_knowledge_find_swt_targets  (     const struct ZoO_knowledge k [const static 1], -   const ZoO_index sequence [const restrict], +   const ZoO_index sequence [restrict static 1],     const size_t sequence_length,     const ZoO_index markov_order, -   const ZoO_index * restrict following_words [const restrict static 1], -   const ZoO_index * restrict following_words_weights [const restrict static 1], -   ZoO_index following_words_weights_sum [const restrict static 1], +   const ZoO_index * restrict targets [const restrict static 1], +   const ZoO_index * restrict targets_weights [const restrict static 1], +   ZoO_index targets_weights_sum [const restrict static 1],     const struct ZoO_pipe io [const restrict static 1]  )  { @@ -224,21 +233,23 @@ int ZoO_knowledge_find_following_words     ZoO_index i, current_min, current_max, local_sequence;     const ZoO_index * restrict candidate;     const ZoO_index markov_sequence_length = (markov_order - 1); -   const size_t sequence_offset = -      ((sequence_length - ((size_t) markov_sequence_length)) - 1); -   const ZoO_index word = sequence[sequence_offset]; +   const ZoO_index word = sequence[sequence_length - 1]; -   if (word >= k->words_length) +   if +   ( +      (word >= k->words_length) +      || (k->words[word].occurrences == 0) +   )     {        ZoO_S_ERROR        (           io, -         "Attempting to find the following words of an unknown word." +         "Attempting to find the SWT targets of an unknown word."        ); -      *following_words = (const ZoO_index *) NULL; -      *following_words_weights = (const ZoO_index *) NULL; -      *following_words_weights_sum = 0; +      *targets = (const ZoO_index *) NULL; +      *targets_weights = (const ZoO_index *) NULL; +      *targets_weights_sum = 0;        return -1;     } @@ -246,30 +257,30 @@ int ZoO_knowledge_find_following_words     if (markov_order == 1)     {        /* Special case: empty sequences. */ -      *following_words = (const ZoO_index *) k->words[word].preceded.targets; +      *targets = (const ZoO_index *) k->words[word].swt.targets; -      *following_words_weights = -         (const ZoO_index *) k->words[word].preceded.targets_occurrences; +      *targets_weights = +         (const ZoO_index *) k->words[word].swt.targets_occurrences; -      *following_words_weights_sum = k->words[word].occurrences; +      *targets_weights_sum = k->words[word].occurrences;        return 0;     } +   sequence = (sequence + (sequence_length - markov_order));     /* Handles the case where the list is empty ********************************/ -   current_max = k->words[word].preceded.sequences_ref_length; +   current_max = k->words[word].swt.sequences_ref_length;     if (current_max == 0)     { -      *following_words = (const ZoO_index *) NULL; -      *following_words_weights = (const ZoO_index *) NULL; -      *following_words_weights_sum = 0; +      *targets = (const ZoO_index *) NULL; +      *targets_weights = (const ZoO_index *) NULL; +      *targets_weights_sum = 0;        ZoO_S_WARNING        (           io, -         "Attempting to find the following words of a sequence that never had " -         "any." +         "Attempting to find the SWT targets of a sequence that never had any."        );        return -2; @@ -283,12 +294,12 @@ int ZoO_knowledge_find_following_words     {        i = (current_min + ((current_max - current_min) / 2)); -      local_sequence = k->words[word].followed.sequences_ref_sorted[i]; +      local_sequence = k->words[word].swt.sequences_ref_sorted[i];        (void) ZoO_knowledge_get_sequence        (           k, -         k->words[word].followed.sequences_ref[local_sequence], +         k->words[word].swt.sequences_ref[local_sequence],           &candidate,           io        ); @@ -296,7 +307,7 @@ int ZoO_knowledge_find_following_words        cmp =           ZoO_sequence_cmp           ( -            (sequence + sequence_offset), +            sequence,              markov_sequence_length,              candidate,              markov_sequence_length @@ -308,9 +319,9 @@ int ZoO_knowledge_find_following_words           if (current_min > current_max)           { -            *following_words = (const ZoO_index *) NULL; -            *following_words_weights = (const ZoO_index *) NULL; -            *following_words_weights_sum = 0; +            *targets = (const ZoO_index *) NULL; +            *targets_weights = (const ZoO_index *) NULL; +            *targets_weights_sum = 0;              return -2;           } @@ -319,9 +330,9 @@ int ZoO_knowledge_find_following_words        {           if ((current_min > current_max) || (i == 0))           { -            *following_words = (const ZoO_index *) NULL; -            *following_words_weights = (const ZoO_index *) NULL; -            *following_words_weights_sum = 0; +            *targets = (const ZoO_index *) NULL; +            *targets_weights = (const ZoO_index *) NULL; +            *targets_weights_sum = 0;              return -2;           } @@ -330,13 +341,13 @@ int ZoO_knowledge_find_following_words        }        else        { -         *following_words = k->words[word].followed.targets[local_sequence]; +         *targets = k->words[word].swt.targets[local_sequence]; -         *following_words_weights = -            k->words[word].followed.targets_occurrences[local_sequence]; +         *targets_weights = +            k->words[word].swt.targets_occurrences[local_sequence]; -         *following_words_weights_sum = -            k->words[word].followed.occurrences[local_sequence]; +         *targets_weights_sum = +            k->words[word].swt.occurrences[local_sequence];           return 0;        } diff --git a/src/knowledge/knowledge_swt_tws_modifications.c b/src/knowledge/knowledge_swt_tws_modifications.c new file mode 100644 index 0000000..87305f2 --- /dev/null +++ b/src/knowledge/knowledge_swt_tws_modifications.c @@ -0,0 +1,29 @@ +#include "knowledge.h" + +int ZoO_knowledge_strengthen_swt +( +   struct ZoO_knowledge k [const restrict static 1], +   const ZoO_index sequence_id, +   const ZoO_index word_id, +   const ZoO_index target_id, +   const struct ZoO_pipe io [const restrict static 1] +) +{ +   /* TODO */ + +   return -1; +} + +int ZoO_knowledge_strengthen_tws +( +   struct ZoO_knowledge k [const restrict static 1], +   const ZoO_index target_id, +   const ZoO_index word_id, +   const ZoO_index sequence_id, +   const struct ZoO_pipe io [const restrict static 1] +) +{ +   /* TODO */ + +   return -1; +} diff --git a/src/knowledge/knowledge_types.h b/src/knowledge/knowledge_types.h index 4962991..9db77bd 100644 --- a/src/knowledge/knowledge_types.h +++ b/src/knowledge/knowledge_types.h @@ -1,6 +1,8 @@  #ifndef _ZoO_KNOWLEDGE_KNOWLEDGE_TYPES_H_  #define _ZoO_KNOWLEDGE_KNOWLEDGE_TYPES_H_ +#include <pthread.h> +  #include "../core/index_types.h"  #include "../core/char_types.h" @@ -20,8 +22,12 @@ struct ZoO_knowledge_word     const ZoO_char * word;     ZoO_index word_length;     ZoO_index occurrences; -   struct ZoO_knowledge_sequence_collection followed; -   struct ZoO_knowledge_sequence_collection preceded; + +   /* [Sequence] [Word] [Target] */ +   struct ZoO_knowledge_sequence_collection swt; + +   /* [Target] [Word] [Sequence] */ +   struct ZoO_knowledge_sequence_collection tws;  };  struct ZoO_knowledge @@ -32,6 +38,7 @@ struct ZoO_knowledge     ZoO_index ** sequences;     ZoO_index sequences_length;     ZoO_index * sequences_sorted; +   pthread_mutex_t mutex;  };  #endif diff --git a/src/pipe/pipe.c b/src/pipe/pipe.c deleted file mode 100644 index 8f414f5..0000000 --- a/src/pipe/pipe.c +++ /dev/null @@ -1 +0,0 @@ -/* TODO */ diff --git a/src/pipe/pipe.h b/src/pipe/pipe.h index 3c5fd44..9b9445c 100644 --- a/src/pipe/pipe.h +++ b/src/pipe/pipe.h @@ -142,6 +142,4 @@           ZoO_PRINT_S_STDERR(pipe, "F", str);\        }\     ) - -/* TODO: add missing pipe functions */  #endif diff --git a/src/pipe/pipe_types.h b/src/pipe/pipe_types.h index cfeb514..91cf0c3 100644 --- a/src/pipe/pipe_types.h +++ b/src/pipe/pipe_types.h @@ -1,6 +1,8 @@  #ifndef _ZoO_PIPE_PIPE_TYPES_H_  #define _ZoO_PIPE_PIPE_TYPES_H_ +#define ZoO_PIPE_NAME_LENGTH 255 +  #include <stdio.h>  struct ZoO_pipe @@ -11,8 +13,8 @@ struct ZoO_pipe  struct ZoO_pipe_names  { -   char request_pipe[255]; -   char reply_pipe[255]; +   char request_pipe[ZoO_PIPE_NAME_LENGTH]; +   char reply_pipe[ZoO_PIPE_NAME_LENGTH];  };  //   const struct ZoO_pipe io [const restrict static 1] diff --git a/src/sequence/sequence_creation.c b/src/sequence/sequence_creation.c index e8ae2a1..429b58c 100644 --- a/src/sequence/sequence_creation.c +++ b/src/sequence/sequence_creation.c @@ -86,7 +86,7 @@ static int extend_left     if     ( -      ZoO_knowledge_find_preceding_words +      ZoO_knowledge_find_tws_targets        (           k,           *sequence, @@ -272,7 +272,7 @@ static int extend_right     if     ( -      ZoO_knowledge_find_following_words +      ZoO_knowledge_find_swt_targets        (           k,           *sequence, @@ -447,12 +447,12 @@ static int initialize_sequence     const struct ZoO_pipe io [const restrict static 1]  )  { -   const ZoO_index * restrict following_sequences_ref; +   const ZoO_index * restrict swt_sequences_ref;     const ZoO_index * restrict chosen_sequence; -   const ZoO_index * restrict following_sequences_weights; -   ZoO_index following_sequences_weights_sum; +   const ZoO_index * restrict swt_sequences_weights; +   ZoO_index swt_sequences_weights_sum; -   sequence[0] = initial_word; +   sequence[(markov_order - 1)] = initial_word;     if (markov_order == 1)     { @@ -463,13 +463,13 @@ static int initialize_sequence     if     ( -      ZoO_knowledge_get_following_sequences_ref +      ZoO_knowledge_get_swt_sequences_ref        (           k,           initial_word, -         &following_sequences_ref, -         &following_sequences_weights, -         &following_sequences_weights_sum, +         &swt_sequences_ref, +         &swt_sequences_weights, +         &swt_sequences_weights_sum,           io        ) < 0     ) @@ -489,12 +489,12 @@ static int initialize_sequence     (void) ZoO_knowledge_get_sequence     (        k, -      following_sequences_ref +      swt_sequences_ref        [           weighted_random_pick           ( -            following_sequences_weights, -            following_sequences_weights_sum +            swt_sequences_weights, +            swt_sequences_weights_sum           )        ],        &chosen_sequence, @@ -504,7 +504,7 @@ static int initialize_sequence     /* Safe if 'allocate_initial_sequence' succeeded. */     memcpy     ( -      (void *) (sequence + 1), +      (void *) sequence,        (const void *) chosen_sequence,        ((((size_t) markov_order) - 1) * sizeof(ZoO_index))     ); diff --git a/src/server/CMakeLists.txt b/src/server/CMakeLists.txt index 2d1beaa..b3f0c15 100644 --- a/src/server/CMakeLists.txt +++ b/src/server/CMakeLists.txt @@ -1,7 +1,16 @@  set(     SRC_FILES ${SRC_FILES}     ${CMAKE_CURRENT_SOURCE_DIR}/server.c +   ${CMAKE_CURRENT_SOURCE_DIR}/server_create_socket.c +   ${CMAKE_CURRENT_SOURCE_DIR}/server_finalize.c +   ${CMAKE_CURRENT_SOURCE_DIR}/server_initialize.c +   ${CMAKE_CURRENT_SOURCE_DIR}/server_joining_threads.c +   ${CMAKE_CURRENT_SOURCE_DIR}/server_new_connection.c +   ${CMAKE_CURRENT_SOURCE_DIR}/server_signals.c +   ${CMAKE_CURRENT_SOURCE_DIR}/server_wait_for_event.c     ${CMAKE_CURRENT_SOURCE_DIR}/server_worker.c +   ${CMAKE_CURRENT_SOURCE_DIR}/server_worker_handle_request.c +   ${CMAKE_CURRENT_SOURCE_DIR}/server_worker_receive.c  )  set(SRC_FILES ${SRC_FILES} PARENT_SCOPE) diff --git a/src/server/server.c b/src/server/server.c index 8a75615..874f5eb 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -1,72 +1,81 @@  #include <signal.h> +#include <string.h>  #include <stdio.h>  #include "../parameters/parameters.h"  #include "server.h" -volatile char ZoO_SERVER_IS_RUNNING = (char) 1; - -static void request_termination (int const signo) +int ZoO_server_main +( +   const struct ZoO_parameters params [const restrict static 1] +)  { -   if ((signo == SIGINT) || (signo == SIGTERM)) +   struct ZoO_server server; +   ZoO_index retries; + +   if (ZoO_server_set_signal_handlers < 0)     { -      ZoO_SERVER_IS_RUNNING = (char) 0; +      return -1;     } -} -int ZoO_server_main (const struct ZoO_parameters params) -{ -   struct ZoO_server server; -   struct ZoO_server_message msg_buffer; -   struct ZoO_server_worker_parameters worker_params; - -   if -   ( -      ZoO_server_initialize -      ( -         &server, -         ZoO_parameters_get_session_name(¶ms) -      ) < 0 -   ) +   if (ZoO_server_initialize(&server, params) < 0)     {        return -1;     } -   ZoO_server_worker_initialize_parameters -   ( -      &worker_params, -      &server, -      &msg_buffer, -      ¶ms -   ); - -   while ((ZoO_SERVER_IS_RUNNING == (char) 1) || (server.running_threads > 0)) +   while (ZoO_server_is_running())     { -      if (ZoO_server_receive_message(&server, &msg_buffer) < 0) +      switch (ZoO_server_wait_for_new_event(&server))        { -         ZoO_server_no_mq_termination(&server); +         case 0: /* Timed out or signal'd. */ +            ZoO_server_handle_joining_threads(&server); + +            retries = 0; + +            break; + +         case 1: /* New client attempted connection. */ +            ZoO_server_handle_joining_threads(&server); +            (void) ZoO_server_handle_new_connection(&server); -         break; +            retries = 0; + +            break; + +         case -1: /* Something bad happened. */ +            retries += 1; + +            if (retries == ZoO_SERVER_MAX_RETRIES) +            { +               ZoO_server_finalize(&server); + +               return -1; +            } + +            break;        } +   } -      switch (msg_buffer.type) +   /* Waiting for the threads to join... */ +   while (server.workers.currently_running > 0) +   { +      switch (ZoO_server_wait_for_new_event(&server))        { -         case 'C': /* Client request */ -            ZoO_server_add_worker(&server, &worker_params); +         case 0: /* Timed out. */ +         case 1: /* New client attempted connection. */ +            ZoO_server_handle_joining_threads(&server);              break; -         case 'J': /* Join request */ -            ZoO_server_finalize_worker(&server, &msg_buffer); -            break; +         case -1: /* Something bad happened. */ +            retries += 1; + +            if (retries == ZoO_SERVER_MAX_RETRIES) +            { +               ZoO_server_finalize(&server); -         default: -            fprintf -            ( -               stderr, -               "[W] Received message with unknown type '%c'.\n", -               msg_buffer.type -            ); +               return -1; +            }              break;        }     } diff --git a/src/server/server.h b/src/server/server.h index f6aa0de..36ec4ce 100644 --- a/src/server/server.h +++ b/src/server/server.h @@ -5,36 +5,54 @@  #include "server_types.h" -int ZoO_server_cleanup_session (const char * session); -  int ZoO_server_initialize  ( -   struct ZoO_server [const restrict static 1], -   const char * session +   struct ZoO_server server [const restrict static 1], +   const struct ZoO_parameters params [const restrict static 1] +); + +int ZoO_server_socket_open +( +   struct ZoO_server_socket server_socket [const restrict static 1], +   const char socket_name [const restrict static 1] +); + +void ZoO_server_request_termination (void); +int ZoO_server_is_running (void); +int ZoO_server_set_signal_handlers (void); + +int ZoO_server_main +( +   const struct ZoO_parameters params [const restrict static 1]  ); -int ZoO_server_main (const struct ZoO_parameters params); -int ZoO_server_finalize (struct ZoO_server [const restrict static 1]); +void ZoO_server_finalize (struct ZoO_server [const restrict static 1]); -void ZoO_server_no_mq_termination (struct ZoO_server [const restrict static 1]); +int ZoO_server_wait_for_new_event +( +   struct ZoO_server server [const restrict static 1] +); -int ZoO_server_receive_message +void ZoO_server_handle_joining_threads  ( -   struct ZoO_server [const restrict static 1], -   struct ZoO_server_message msg_buffer [const restrict static 1] +   struct ZoO_server server [const restrict static 1]  ); -int ZoO_server_add_worker +int ZoO_server_handle_new_connection +( +   struct ZoO_server server [const restrict static 1] +); + +void * ZoO_server_worker_main (void * input); + +int ZoO_server_worker_receive  ( -   struct ZoO_server s [const restrict static 1], -   struct ZoO_server_message msg_buffer [const restrict static 1], -   struct ZoO_worker_parameters worker_params [const restrict static 1] +   struct ZoO_server_worker worker [const restrict static 1]  ); -int ZoO_server_finalize_worker +int ZoO_server_worker_handle_request  ( -   struct ZoO_server [const restrict static 1], -   struct ZoO_server_message msg_buffer [const restrict static 1] +   struct ZoO_server_worker worker [const restrict static 1]  );  #endif diff --git a/src/server/server_add_server_worker.c b/src/server/server_add_server_worker.c deleted file mode 100644 index cae10fd..0000000 --- a/src/server/server_add_server_worker.c +++ /dev/null @@ -1,13 +0,0 @@ -#include <pthread.h> - -#include "server.h" - -int ZoO_server_add_worker -( -   struct ZoO_server s [const restrict static 1], -   struct ZoO_server_message msg_buffer [const restrict static 1] -) -{ -   /* TODO */ -   return -1; -} diff --git a/src/server/server_create_socket.c b/src/server/server_create_socket.c new file mode 100644 index 0000000..77e55b7 --- /dev/null +++ b/src/server/server_create_socket.c @@ -0,0 +1,188 @@ +#include <errno.h> +#include <fcntl.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +#include <sys/socket.h> +#include <sys/un.h> + +#include "server.h" + +static int create_socket (int result [const restrict static 1]) +{ +   const int old_errno = errno; + +   errno = 0; +   *result = socket(AF_UNIX, SOCK_STREAM, 0); + +   if (*result == -1) +   { +      fprintf +      ( +         stderr, +         "[F] Unable to create server socket: %s.\n", +         strerror(errno) +      ); + +      errno = old_errno; + +      return -1; +   } + +   errno = old_errno; + +   return 0; +} + +static int bind_socket +( +   const int socket, +   const char socket_name [const restrict static 1] +) +{ +   struct sockaddr_un addr; +   const int old_errno = errno; + +   errno = 0; +   memset(&addr, 0, sizeof(struct sockaddr_un)); + +   addr.sun_family = AF_UNIX; + +   /* addr.sun_path == 108. Using 107 ensure null-termination. */ +   strncpy(addr.sun_path, socket_name, 107); + +   errno = old_errno; + +   if +   ( +      bind +      ( +         socket, +         (const struct sockaddr *) &addr, +         (socklen_t) sizeof(struct sockaddr_un) +      ) != 0 +   ) +   { +      fprintf +      ( +         stderr, +         "[F] Unable to bind server socket to %s: %s.\n", +         socket_name, +         strerror(errno) +      ); + +      errno = old_errno; + +      return -1; +   } + +   errno = old_errno; + +   return 0; +} + +static int set_socket_to_unblocking (const int socket) +{ +   int current_flags; +   const int old_errno = errno; + +   current_flags = fcntl(socket, F_GETFD); + +   if (current_flags == -1) +   { +      fprintf +      ( +         stderr, +         "[F] Unable to get server socket properties: %s.\n", +         strerror(errno) +      ); + +      errno = old_errno; + +      return -1; +   } + +   /* current_flags = current_flags & (~O_NONBLOCK); */ + +   current_flags = fcntl(socket, F_SETFD, (current_flags | O_NONBLOCK)); + +   if (current_flags == -1) +   { +      fprintf +      ( +         stderr, +         "[F] Unable to set server socket properties: %s.\n", +         strerror(errno) +      ); + +      errno = old_errno; + +      return -2; +   } + +   errno = old_errno; + +   return 0; +} + +static int set_socket_as_listener (const int socket) +{ +   const int old_errno = errno; + +   if (listen(socket, ZoO_SERVER_SOCKET_LISTEN_BACKLOG) != 0) +   { +      fprintf +      ( +         stderr, +         "[F] Unable to set server socket properties: %s.\n", +         strerror(errno) +      ); + +      errno = old_errno; + +      return -1; +   } + +   errno = old_errno; + +   return 0; +} + +int ZoO_server_socket_open +( +   struct ZoO_server_socket server_socket [const restrict static 1], +   const char socket_name [const restrict static 1] +) +{ +   if (create_socket(&(server_socket->file_descriptor)) < 0) +   { +      return -1; +   } + +   if (bind_socket(server_socket->file_descriptor, socket_name) < 0) +   { +      close(server_socket->file_descriptor); + +      return -1; +   } + +   if (set_socket_to_unblocking(server_socket->file_descriptor) < 0) +   { +      close(server_socket->file_descriptor); + +      return -1; +   } + +   if (set_socket_as_listener(server_socket->file_descriptor) < 0) +   { +      close(server_socket->file_descriptor); + +      return -1; +   } + +   FD_ZERO(&(server_socket->as_a_set)); +   FD_SET(server_socket->file_descriptor, &(server_socket->as_a_set)); + +   return 0; +} diff --git a/src/server/server_finalize.c b/src/server/server_finalize.c new file mode 100644 index 0000000..c38fb7d --- /dev/null +++ b/src/server/server_finalize.c @@ -0,0 +1,42 @@ +#include <stdlib.h> +#include <unistd.h> + +#include "../parameters/parameters.h" + +#include "server.h" + +static void finalize_thread_collection +( +   struct ZoO_server_thread_collection workers [const restrict static 1] +) +{ +   free((void *) workers->threads); + +   workers->threads_capacity = 0; + +   pthread_mutex_destroy(&(workers->mutex)); +   pthread_barrier_destroy(&(workers->barrier)); + +   workers->currently_running = 0; +} + +static void finalize_socket +( +   struct ZoO_server_socket socket [const restrict static 1] +) +{ +   FD_ZERO(&(socket->as_a_set)); + +   close(socket->file_descriptor); + +   socket->file_descriptor = -1; +} + +void ZoO_server_finalize +( +   struct ZoO_server server [const restrict static 1] +) +{ +   finalize_thread_collection(&(server->workers)); +   finalize_socket(&(server->socket)); +} diff --git a/src/server/server_initialize.c b/src/server/server_initialize.c new file mode 100644 index 0000000..9213156 --- /dev/null +++ b/src/server/server_initialize.c @@ -0,0 +1,99 @@ +#include <signal.h> +#include <string.h> +#include <stdio.h> + +#include "../parameters/parameters.h" + +#include "server.h" + +static int initialize_worker_collection +( +   struct ZoO_server_thread_collection c [const restrict static 1] +) +{ +	int error; + +	c->threads = (struct ZoO_server_thread_data *) NULL; +	c->threads_capacity = 0; +   c->currently_running = 0; + +	error = +		pthread_mutex_init +		( +			&(c->mutex), +			(const pthread_mutexattr_t *) NULL +		); + +	if (error != 0) +	{ +		fprintf +		( +			stderr, +         "[F] Unable to initialize worker collection's mutex: %s.\n", +         strerror(error) +		); + +      return -1; +	} + +   error = +      pthread_barrier_init +      ( +         &(c->barrier), +         (const pthread_barrierattr_t *) NULL, +         2 +      ); + +   if (error != 0) +	{ +		fprintf +		( +			stderr, +         "[F] Unable to initialize worker collection's barrier: %s.\n", +         strerror(error) +		); + +      return -1; +	} + +   return 0; +} + +void initialize_thread_parameters +( +   struct ZoO_server server [const restrict static 1], +   const struct ZoO_parameters params [const restrict static 1] +) +{ +   server->thread_params.thread_collection = &(server->workers); +   server->thread_params.server_params = params; +   server->thread_params.socket = -1; +} + +int ZoO_server_initialize +( +   struct ZoO_server server [const restrict static 1], +   const struct ZoO_parameters params [const restrict static 1] +) +{ +   if (initialize_worker_collection(&(server->workers)) < 0) +   { +      return -1; +   } + +   if +   ( +      ZoO_server_socket_open +      ( +         &(server->socket), +         ZoO_parameters_get_session_name(params) +      ) < 0 +   ) +   { +      return -2; +   } + +   initialize_thread_parameters(server, params); + +   return 0; +} diff --git a/src/server/server_joining_threads.c b/src/server/server_joining_threads.c new file mode 100644 index 0000000..48b5ac6 --- /dev/null +++ b/src/server/server_joining_threads.c @@ -0,0 +1,36 @@ +#include <sys/socket.h> + +#include <errno.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <unistd.h> + +#include "../parameters/parameters.h" + +#include "server.h" + +void ZoO_server_handle_joining_threads +( +   struct ZoO_server server [const restrict static 1] +) +{ +   ZoO_index i; + +   pthread_mutex_lock(&(server->workers.mutex)); + +   for (i = 0; i < server->workers.threads_capacity; ++i) +   { +      if (server->workers.threads[i].state == ZoO_SERVER_JOINING_THREAD) +      { +         pthread_join(server->workers.threads[i].posix_id, (void **) NULL); + +         server->workers.threads[i].state = ZoO_SERVER_NO_THREAD; + +         server->workers.currently_running -= 1; +      } +   } + +   pthread_mutex_unlock(&(server->workers.mutex)); +} diff --git a/src/server/server_new_connection.c b/src/server/server_new_connection.c new file mode 100644 index 0000000..5392de5 --- /dev/null +++ b/src/server/server_new_connection.c @@ -0,0 +1,181 @@ +#include <sys/socket.h> + +#include <errno.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <unistd.h> + +#include "../parameters/parameters.h" + +#include "server.h" + +static int get_new_socket (struct ZoO_server server [const restrict static 1]) +{ +   const int old_errno = errno; + +   server->thread_params.socket = +      accept +      ( +         server->socket.file_descriptor, +         (struct sockaddr *) NULL, +         (socklen_t *) NULL +      ); + +   if (server->thread_params.socket == -1) +   { +      fprintf +      ( +         stderr, +         "[E] Unable to accept on the server's socket: %s.\n", +         strerror(errno) +      ); + +      errno = old_errno; + +      return -1; +   } + +   errno = old_errno; + +   return 0; +} + +static int get_new_thread (struct ZoO_server server [const restrict static 1]) +{ +   struct ZoO_server_thread_data * new_threads; +   ZoO_index i; + +   pthread_mutex_lock(&(server->workers.mutex)); + +   for (i = 0; i < server->workers.threads_capacity; ++i) +   { +      if (server->workers.threads[i].state == ZoO_SERVER_NO_THREAD) +      { +         server->thread_params.thread_id = i; + +         pthread_mutex_unlock(&(server->workers.mutex)); + +         return 0; +      } +   } + +   if +   ( +      (server->workers.threads_capacity == ZoO_INDEX_MAX) +      || +      ( +         (size_t) (server->workers.threads_capacity + 1) +         > (SIZE_MAX / sizeof(struct ZoO_server_thread_data)) +      ) +   ) +   { +      fprintf +      ( +         stderr, +         "[E] Maximum number of concurrent threads attained, unable to add" +         " more.\n" +      ); + +      pthread_mutex_unlock(&(server->workers.mutex)); + +      return -1; +   } + +   server->thread_params.thread_id = server->workers.threads_capacity; +   server->workers.threads_capacity += 1; + +   new_threads = +      (struct ZoO_server_thread_data *) realloc +      ( +         &(server->workers.threads), +         ( +            sizeof(struct ZoO_server_thread_data) +            * ((size_t) server->workers.threads_capacity) +         ) +      ); + +   if (new_threads == ((struct ZoO_server_thread_data *) NULL)) +   { +      fprintf +      ( +         stderr, +         "[E] Reallocation of the threads' data list failed.\n" +      ); + +      pthread_mutex_unlock(&(server->workers.mutex)); + +      return -1; +   } + +   server->workers.threads = new_threads; + +   pthread_mutex_unlock(&(server->workers.mutex)); + +   return 0; +} + +static int spawn_thread (struct ZoO_server server [const restrict static 1]) +{ +   const ZoO_index thread_id = server->thread_params.thread_id; +   int error; + +   server->workers.threads[thread_id].state = ZoO_SERVER_RUNNING_THREAD; + +   error = +      pthread_create +      ( +         &(server->workers.threads[thread_id].posix_id), +         (const pthread_attr_t *) NULL, +         ZoO_server_worker_main, +         (void *) &(server->thread_params) +      ); + +   if (error != 0) +   { +      fprintf +      ( +         stderr, +         "[E] Unable to spawn thread: %s.\n", +         strerror(error) +      ); + +      server->workers.threads[thread_id].state = ZoO_SERVER_NO_THREAD; + +      return -1; +   } + +   pthread_barrier_wait(&(server->workers.barrier)); + +   server->workers.currently_running += 1; + +   return 0; +} + +int ZoO_server_handle_new_connection +( +   struct ZoO_server server [const restrict static 1] +) +{ +   if (get_new_socket(server) < 0) +   { +      return -1; +   } + +   if (get_new_thread(server) < 0) +   { +      close(server->thread_params.socket); + +      return -2; +   } + +   if (spawn_thread(server) < 0) +   { +      close(server->thread_params.socket); + +      return -3; +  } + +   return 0; +} diff --git a/src/server/server_signal.c b/src/server/server_signal.c new file mode 100644 index 0000000..97137e8 --- /dev/null +++ b/src/server/server_signal.c @@ -0,0 +1,41 @@ +#include <signal.h> +#include <string.h> +#include <stdio.h> + +#include "server.h" + +static volatile char ZoO_SERVER_IS_RUNNING = (char) 1; + +static void request_termination (int const signo) +{ +   if ((signo == SIGINT) || (signo == SIGTERM)) +   { +      ZoO_server_request_termination(); +   } +} + +void ZoO_server_request_termination (void) +{ +   ZoO_SERVER_IS_RUNNING = (char) 0; +} + +int ZoO_server_is_running (void) +{ +   return (int) ZoO_SERVER_IS_RUNNING; +} + +int ZoO_server_set_signal_handlers (void) +{ +   struct sigaction act; + +   /* +      act.sa_handler = request_termination; +      act.sa_mask = +      act.sa_flags = +      act.sa_restorer = +   */ + +   /* TODO */ + +   return -1; +} diff --git a/src/server/server_types.h b/src/server/server_types.h index aeb0ec8..99959f5 100644 --- a/src/server/server_types.h +++ b/src/server/server_types.h @@ -1,27 +1,70 @@  #ifndef _ZoO_SERVER_SERVER_TYPES_H_  #define _ZoO_SERVER_SERVER_TYPES_H_ -#include <mqueue.h> +#include <sys/time.h> + +#include <pthread.h>  #include "../core/index.h"  #include "../pipe/pipe_types.h" -struct ZoO_server_message +#define ZoO_SERVER_MAX_RETRIES 10 +#define ZoO_SERVER_BUFFER_SIZE 0 + +#define ZoO_SERVER_SOCKET_ACCEPT_TIMEOUT_SEC 60 +#define ZoO_SERVER_SOCKET_LISTEN_BACKLOG     5 + +enum ZoO_server_thread_state +{ +   ZoO_SERVER_JOINING_THREAD, +   ZoO_SERVER_RUNNING_THREAD, +   ZoO_SERVER_NO_THREAD +}; + +struct ZoO_server_thread_data +{ +   pthread_t posix_id; +   enum ZoO_server_thread_state state; +}; + +struct ZoO_server_thread_collection +{ +   struct ZoO_server_thread_data * threads; +   size_t threads_capacity; +   pthread_mutex_t mutex; +   pthread_barrier_t barrier; +   ZoO_index currently_running; +}; + +struct ZoO_server_socket +{ +   int file_descriptor; +   fd_set as_a_set; +   struct timeval timeout; +}; + +struct ZoO_server_thread_parameters +{ +   struct ZoO_server_thread_collection * thread_collection; +   const struct ZoO_parameters * server_params; +   ZoO_index thread_id; +   int socket; +}; + +struct ZoO_server_worker  { -   char type; -   union -   { -      struct ZoO_pipe_names pipe_names; -      ZoO_index pthread_id; -   } data; +   char * buffer; +   size_t buffer_capacity; +   size_t buffer_length; +   struct ZoO_server_thread_parameters params;  };  struct ZoO_server  { -   /* TODO: insert 2 thread barrier. */ -   mqd_t mailbox; -   ZoO_index running_threads; +   struct ZoO_server_thread_collection workers; +   struct ZoO_server_socket socket; +   struct ZoO_server_thread_parameters thread_params;  };  #endif diff --git a/src/server/server_wait_for_event.c b/src/server/server_wait_for_event.c new file mode 100644 index 0000000..b229e6b --- /dev/null +++ b/src/server/server_wait_for_event.c @@ -0,0 +1,53 @@ +#include <sys/select.h> + +#include <errno.h> +#include <stdio.h> +#include <string.h> + +#include "server.h" + +int ZoO_server_wait_for_event +( +   struct ZoO_server server [const static 1] +) +{ +   int ready_fds; +   const int old_errno = errno; + +   /* call to select may alter timeout */ +   memset((void *) &(server->socket.timeout), 0, sizeof(struct timeval)); + +   server->socket.timeout.tv_sec = ZoO_SERVER_SOCKET_ACCEPT_TIMEOUT_SEC; + +   ready_fds = select +   ( +      (server->socket.file_descriptor + 1), +      &(server->socket.as_a_set), +      (fd_set *) NULL, +      (fd_set *) NULL, +      &(server->socket.timeout) +   ); + +   if (errno == EINTR) +   { +      ready_fds = 0; +   } + +   if (ready_fds == -1) +   { +      fprintf +      ( +         stderr, +         "[F] Unable to wait on server socket: %s.\n", +         strerror(errno) +      ); + +      errno = old_errno; + +      return -1; +   } + +   errno = old_errno; + +   return ready_fds; +} diff --git a/src/server/server_worker.c b/src/server/server_worker.c index 04f71ca..f6378e0 100644 --- a/src/server/server_worker.c +++ b/src/server/server_worker.c @@ -1,21 +1,62 @@ -#include "worker.h" +#include <signal.h> +#include <string.h> +#include <stdio.h> -void ZoO_worker_initialize_parameters +#include "server.h" + +static void initialize +( +   struct ZoO_server_worker worker [const restrict static 1], +   void * input +) +{ +   memcpy +   ( +      (void *) &(worker->params), +      (const void *) input, +      sizeof(struct ZoO_server_thread_parameters) +   ); + +   pthread_barrier_wait(&(worker->params.thread_collection->barrier)); + +   worker->buffer = (char *) NULL; +   worker->buffer_capacity = 0; +   worker->buffer_length = 0; +} + +static void finalize  ( -   struct ZoO_worker_parameters worker_params; -   const struct ZoO_server_message msg_buffer [const restrict static 1], -   const struct ZoO_parameters params [const restrict static 1] +   struct ZoO_server_worker worker [const restrict static 1]  )  { -   worker_params->thread_id = 0; -   pthread_barrier_t * barrier; -   mqd_t * server_mailbox; -   const struct ZoO_pipe_names * pipe_names; +   pthread_mutex_lock(&(worker->params.thread_collection->mutex)); + +   worker->params.thread_collection->threads[worker->params.thread_id].state = +      ZoO_SERVER_JOINING_THREAD; + +   pthread_mutex_unlock(&(worker->params.thread_collection->mutex)); +} + +void * ZoO_server_worker_main (void * input) +{ +   struct ZoO_server_worker worker; + +   initialize(&worker, input); + +   while (ZoO_server_is_running()) +   { +      if (ZoO_server_worker_receive(&worker) < 0) +      { +         break; +      } + +      if (ZoO_server_worker_handle_request(&worker) < 0) +      { +         break; +      } +   } -   /* Program data */ -   ZoO_index markov_order; -   struct ZoO_knowledge * k; -   const char * storage_filename; +   finalize(&worker); -   /* TODO */ +   return NULL;  } diff --git a/src/server/server_worker.h b/src/server/server_worker.h deleted file mode 100644 index 825cc11..0000000 --- a/src/server/server_worker.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _ZoO_WORKER_WORKER_H_ -#define _ZoO_WORKER_WORKER_H_ - -#include "../parameters/parameters_types.h" - -#include "worker_types.h" - -#endif diff --git a/src/server/server_worker_handle_request.c b/src/server/server_worker_handle_request.c new file mode 100644 index 0000000..0c97091 --- /dev/null +++ b/src/server/server_worker_handle_request.c @@ -0,0 +1,11 @@ +#include "server.h" + +int ZoO_server_worker_handle_request +( +   struct ZoO_server_worker worker [const restrict static 1] +) +{ +   /* TODO */ + +   return 0; +} diff --git a/src/server/server_worker_receive.c b/src/server/server_worker_receive.c new file mode 100644 index 0000000..6e70159 --- /dev/null +++ b/src/server/server_worker_receive.c @@ -0,0 +1,11 @@ +#include "server.h" + +int ZoO_server_worker_receive +( +   struct ZoO_server_worker worker [const restrict static 1] +) +{ +   /* TODO */ + +   return 0; +} diff --git a/src/server/server_worker_types.h b/src/server/server_worker_types.h deleted file mode 100644 index 07757bd..0000000 --- a/src/server/server_worker_types.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _ZoO_WORKER_WORKER_TYPES_H_ -#define _ZoO_WORKER_WORKER_TYPES_H_ - -#include <mqueue.h> - -#include "../core/index_types.h" - -#include "../pipes/pipes_types.h" - -#include "../knowledge/knowledge_types.h" - - -struct ZoO_worker_parameters -{ -   /* Communication data */ -   ZoO_index thread_id; -   pthread_barrier_t * barrier; -   mqd_t * server_mailbox; -   const struct ZoO_pipe_names * pipe_names; - -   /* Program data */ -   ZoO_index markov_order; -   struct ZoO_knowledge * k; -   const char * storage_filename; -}; - -#endif  | 


