]> git.sesse.net Git - pistorm/blob - a314/a314device/sockets.c
Add missing copyright to A314 source files
[pistorm] / a314 / a314device / sockets.c
1 /*
2  * Copyright 2020-2021 Niklas Ekström
3  */
4
5 #include <proto/exec.h>
6
7 #include "sockets.h"
8
9 struct List active_sockets;
10
11 struct Socket *send_queue_head = NULL;
12 struct Socket *send_queue_tail = NULL;
13
14 static UBYTE next_stream_id = 1;
15
16 extern void NewList(struct List *l);
17
18 void init_sockets()
19 {
20         NewList(&active_sockets);
21 }
22
23 struct Socket *find_socket(void *sig_task, ULONG socket)
24 {
25         for (struct Node *node = active_sockets.lh_Head; node->ln_Succ != NULL; node = node->ln_Succ)
26         {
27                 struct Socket *s = (struct Socket *)node;
28                 if (s->sig_task == sig_task && s->socket == socket)
29                         return s;
30         }
31         return NULL;
32 }
33
34 struct Socket *find_socket_by_stream_id(UBYTE stream_id)
35 {
36         for (struct Node *node = active_sockets.lh_Head; node->ln_Succ != NULL; node = node->ln_Succ)
37         {
38                 struct Socket *s = (struct Socket *)node;
39                 if (s->stream_id == stream_id)
40                         return s;
41         }
42         return NULL;
43 }
44
45 static UBYTE allocate_stream_id()
46 {
47         // Bug: If all stream ids are allocated then this loop won't terminate.
48
49         while (1)
50         {
51                 UBYTE stream_id = next_stream_id;
52                 next_stream_id += 2;
53                 if (find_socket_by_stream_id(stream_id) == NULL)
54                         return stream_id;
55         }
56 }
57
58 static void free_stream_id(UBYTE stream_id)
59 {
60         // Currently do nothing.
61         // Could speed up allocate_stream_id using a bitmap?
62 }
63
64 struct Socket *create_socket(struct Task *task, ULONG id)
65 {
66         struct Socket *s = (struct Socket *)AllocMem(sizeof(struct Socket), MEMF_CLEAR);
67         s->sig_task = task;
68         s->socket = id;
69         s->stream_id = allocate_stream_id();
70         AddTail(&active_sockets, (struct Node *)s);
71         return s;
72 }
73
74 void delete_socket(struct Socket *s)
75 {
76         Remove((struct Node *)s);
77         free_stream_id(s->stream_id);
78         FreeMem(s, sizeof(struct Socket));
79 }
80
81 void add_to_send_queue(struct Socket *s, UWORD required_length)
82 {
83         s->send_queue_required_length = required_length;
84         s->next_in_send_queue = NULL;
85
86         if (send_queue_head == NULL)
87                 send_queue_head = s;
88         else
89                 send_queue_tail->next_in_send_queue = s;
90         send_queue_tail = s;
91
92         s->flags |= SOCKET_IN_SEND_QUEUE;
93 }
94
95 void remove_from_send_queue(struct Socket *s)
96 {
97         if (s->flags & SOCKET_IN_SEND_QUEUE)
98         {
99                 if (send_queue_head == s)
100                 {
101                         send_queue_head = s->next_in_send_queue;
102                         if (send_queue_head == NULL)
103                                 send_queue_tail = NULL;
104                 }
105                 else
106                 {
107                         struct Socket *curr = send_queue_head;
108                         while (curr->next_in_send_queue != s)
109                                 curr = curr->next_in_send_queue;
110
111                         curr->next_in_send_queue = s->next_in_send_queue;
112                         if (send_queue_tail == s)
113                                 send_queue_tail = curr;
114                 }
115
116                 s->next_in_send_queue = NULL;
117                 s->flags &= ~SOCKET_IN_SEND_QUEUE;
118         }
119 }