summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2017-01-31 16:21:24 +0100
committerNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2017-01-31 16:21:24 +0100
commit509ac16d892aeb5091f68620247f6815d2e4b5f5 (patch)
treec4adebce7791c10c4c362b77f32d4a339e8c8125
parent1373211465c34015ee900e097aa87fbffb401187 (diff)
Switched to sockets, continuing implementation...
-rw-r--r--src/knowledge/knowledge.c26
-rw-r--r--src/knowledge/knowledge.h66
-rw-r--r--src/knowledge/knowledge_finalize.c6
-rw-r--r--src/knowledge/knowledge_learn_markov_sequence.c55
-rw-r--r--src/knowledge/knowledge_learn_sequence.c192
-rw-r--r--src/knowledge/knowledge_learn_word.c4
-rw-r--r--src/knowledge/knowledge_search.c153
-rw-r--r--src/knowledge/knowledge_swt_tws_modifications.c29
-rw-r--r--src/knowledge/knowledge_types.h11
-rw-r--r--src/pipe/pipe.c1
-rw-r--r--src/pipe/pipe.h2
-rw-r--r--src/pipe/pipe_types.h6
-rw-r--r--src/sequence/sequence_creation.c28
-rw-r--r--src/server/CMakeLists.txt9
-rw-r--r--src/server/server.c99
-rw-r--r--src/server/server.h52
-rw-r--r--src/server/server_add_server_worker.c13
-rw-r--r--src/server/server_create_socket.c188
-rw-r--r--src/server/server_finalize.c42
-rw-r--r--src/server/server_initialize.c99
-rw-r--r--src/server/server_joining_threads.c36
-rw-r--r--src/server/server_new_connection.c181
-rw-r--r--src/server/server_signal.c41
-rw-r--r--src/server/server_types.h65
-rw-r--r--src/server/server_wait_for_event.c53
-rw-r--r--src/server/server_worker.c69
-rw-r--r--src/server/server_worker.h8
-rw-r--r--src/server/server_worker_handle_request.c11
-rw-r--r--src/server/server_worker_receive.c11
-rw-r--r--src/server/server_worker_types.h27
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(&params)
- ) < 0
- )
+ if (ZoO_server_initialize(&server, params) < 0)
{
return -1;
}
- ZoO_server_worker_initialize_parameters
- (
- &worker_params,
- &server,
- &msg_buffer,
- &params
- );
-
- 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