aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel Gavin <danielgavin5@hotmail.com>2022-01-23 00:17:04 +0100
committerDaniel Gavin <danielgavin5@hotmail.com>2022-01-23 00:17:04 +0100
commit7e39136c69e8d29b2f1f3f804aa72c6e655a5691 (patch)
tree6cd90e79c7cabfec6b37e6040a173427bee8f8ff /src
parentae6eca0290a8ffce82727b3f71700ff34490693b (diff)
work on new request flow
Diffstat (limited to 'src')
-rw-r--r--src/server/requests.odin94
1 files changed, 55 insertions, 39 deletions
diff --git a/src/server/requests.odin b/src/server/requests.odin
index dac74ba..361c0cb 100644
--- a/src/server/requests.odin
+++ b/src/server/requests.odin
@@ -81,19 +81,16 @@ RequestThreadData :: struct {
}
Request :: struct {
- id: RequestId,
- value: json.Value,
-}
-RequestNotification :: struct {
- index: int,
- value: json.Value,
+ id: RequestId,
+ value: json.Value,
+ is_notification: bool,
}
+
requests_sempahore: sync.Semaphore;
requests_mutex: sync.Mutex;
requests: [dynamic]Request;
-notifications: [dynamic]RequestNotification;
deletings: [dynamic]Request;
thread_request_main :: proc(data: rawptr) {
@@ -142,15 +139,10 @@ thread_request_main :: proc(data: rawptr) {
method := root["method"].(json.String);
if method == "$/cancelRequest" {
-
- } else if strings.contains(method, "textDocument/did") || method == "exit" {
- if len(requests) > 0 {
- append(&notifications, RequestNotification { index = len(requests)-1, value = root});
- sync.semaphore_post(&requests_sempahore);
- } else {
- append(&notifications, RequestNotification { index = -1, value = root});
- sync.semaphore_post(&requests_sempahore);
- }
+ append(&deletings, Request { id = id });
+ } else if method in notification_map {
+ append(&requests, Request { value = root, is_notification = true});
+ sync.semaphore_post(&requests_sempahore);
} else {
append(&requests, Request { id = id, value = root});
sync.semaphore_post(&requests_sempahore);
@@ -270,42 +262,56 @@ call_map : map [string] proc(json.Value, RequestId, ^common.Config, ^Writer) ->
"textDocument/documentLink" = request_document_links,
};
+notification_map: map [string] bool = {
+ "textDocument/didOpen" = true,
+ "textDocument/didChange" = true,
+ "textDocument/didClose" = true,
+ "textDocument/didSave" = true,
+ "initialized" = true,
+}
+
consume_requests :: proc (config: ^common.Config, writer: ^Writer) -> bool {
temp_requests := make([dynamic]Request, 0, context.temp_allocator);
- temp_notifications := make([dynamic]RequestNotification, 0, context.temp_allocator);
sync.mutex_lock(&requests_mutex);
+ for d in deletings {
+ delete_index := -1;
+ for request, i in requests {
+ if request.id == d.id {
+ delete_index := i;
+ break;
+ }
+ }
+ if delete_index != -1 {
+ cancel(requests[delete_index].value, requests[delete_index].id, writer, config);
+ ordered_remove(&requests, delete_index);
+ }
+ }
+
for request in requests {
append(&temp_requests, request);
}
- for notification in notifications {
- append(&temp_notifications, notification);
- }
+ sync.mutex_unlock(&requests_mutex);
+
+ request_index := 0;
- clear(&requests);
- clear(&notifications);
+ for ; request_index < len(temp_requests); request_index += 1 {
+ request := temp_requests[request_index];
+ call(request.value, request.id, writer, config);
+ }
+ sync.mutex_lock(&requests_mutex);
+
+ for i := 0; i < request_index; i += 1 {
+ pop_front(&requests);
+ }
+
sync.mutex_unlock(&requests_mutex);
- outer: for len(temp_notifications) > 0 || len(temp_requests) > 0 {
- if len(temp_notifications) > 0 {
- for notification in temp_notifications {
- for request, i in temp_requests {
- if notification.index >= i {
- call(request.value, request.id, writer, config);
- } else {
- break;
- }
- }
- call(notification.value, 0, writer, config);
- }
- } else {
- for request, i in temp_requests {
- call(request.value, request.id, writer, config);
- }
- }
+ if request_index != len(temp_requests) {
+ sync.semaphore_post(&requests_sempahore);
}
sync.semaphore_wait_for(&requests_sempahore);
@@ -313,6 +319,16 @@ consume_requests :: proc (config: ^common.Config, writer: ^Writer) -> bool {
return true;
}
+
+cancel :: proc(value: json.Value, id: RequestId, writer: ^Writer, config: ^common.Config) {
+ response := make_response_message(
+ id = id,
+ params = ResponseParams {},
+ );
+
+ send_response(response, writer);
+}
+
call :: proc(value: json.Value, id: RequestId, writer: ^Writer, config: ^common.Config) {
root := value.(json.Object);
method := root["method"].(json.String);