Browse Source

Fix race condition caused by parallelized parser: #211

gingerBill 7 years ago
parent
commit
e2eca45188
1 changed files with 19 additions and 7 deletions
  1. 19 7
      src/parser.cpp

+ 19 - 7
src/parser.cpp

@@ -4213,6 +4213,11 @@ ParseFileError parse_import(Parser *p, ImportedFile imported_file) {
 			break;
 			break;
 		}
 		}
 		gb_printf_err("\n");
 		gb_printf_err("\n");
+
+		gb_mutex_lock(&global_error_collector.mutex);
+		global_error_collector.count++;
+		gb_mutex_unlock(&global_error_collector.mutex);
+
 		return err;
 		return err;
 	}
 	}
 
 
@@ -4296,6 +4301,8 @@ ParseFileError parse_files(Parser *p, String init_filename) {
 			gb_thread_destroy(&worker_threads[i]);
 			gb_thread_destroy(&worker_threads[i]);
 		});
 		});
 
 
+		auto errors = array_make<ParseFileError>(heap_allocator(), 0, 16);
+
 		for (;;) {
 		for (;;) {
 			bool are_any_alive = false;
 			bool are_any_alive = false;
 			for_array(i, worker_threads) {
 			for_array(i, worker_threads) {
@@ -4303,20 +4310,25 @@ ParseFileError parse_files(Parser *p, String init_filename) {
 				if (gb_thread_is_running(t)) {
 				if (gb_thread_is_running(t)) {
 					are_any_alive = true;
 					are_any_alive = true;
 				} else if (curr_import_index < p->imports.count) {
 				} else if (curr_import_index < p->imports.count) {
-					auto err = cast(ParseFileError)t->return_value;
-					if (err != ParseFile_None) {
-						return err;
+					auto curr_err = cast(ParseFileError)t->return_value;
+					if (curr_err != ParseFile_None) {
+						array_add(&errors, curr_err);
+					} else {
+						t->user_index = curr_import_index;
+						curr_import_index++;
+						gb_thread_start(t, parse_worker_file_proc, p);
+						are_any_alive = true;
 					}
 					}
-					t->user_index = curr_import_index;
-					curr_import_index++;
-					gb_thread_start(t, parse_worker_file_proc, p);
-					are_any_alive = true;
 				}
 				}
 			}
 			}
 			if (!are_any_alive && curr_import_index >= p->imports.count) {
 			if (!are_any_alive && curr_import_index >= p->imports.count) {
 				break;
 				break;
 			}
 			}
 		}
 		}
+
+		if (errors.count > 0) {
+			return errors[errors.count-1];
+		}
 	} else {
 	} else {
 		for_array(i, p->imports) {
 		for_array(i, p->imports) {
 			ParseFileError err = parse_import(p, p->imports[i]);
 			ParseFileError err = parse_import(p, p->imports[i]);