]> git.lizzy.rs Git - dragonnet.git/blob - recv_thread.c
47a47a833c4ecf39ae7183e56af147ac5265811d
[dragonnet.git] / recv_thread.c
1 #include <assert.h>
2 #include <dragontype/number.h>
3 #include <errno.h>
4 #include <pthread.h>
5 #include <stdbool.h>
6 #include <stdio.h>
7 #include <unistd.h>
8
9 #include "peer.h"
10 #include "recv_thread.h"
11
12 void *dragonnet_peer_recv_thread(void *g_peer)
13 {
14         DragonnetPeer *p = (DragonnetPeer *) g_peer;
15
16         pthread_rwlock_wrlock(&p->mu);
17         assert(p->state == DRAGONNET_PEER_CREATED);
18         p->state++;
19         pthread_rwlock_unlock(&p->mu);
20
21         while (true) {
22                 u16 msg;
23
24                 pthread_rwlock_rdlock(&p->mu);
25                 ssize_t len = recv(p->sock, &msg, sizeof msg, MSG_WAITALL);
26                 pthread_rwlock_unlock(&p->mu);
27
28                 if (len < 0 && errno != EWOULDBLOCK) {
29                         perror("recv");
30                         dragonnet_peer_delete(p);
31                         return NULL;
32                 }
33
34                 // connection closed
35                 if ((len >= 0 && len != sizeof msg) || errno == EWOULDBLOCK) {
36                         pthread_rwlock_wrlock(&p->mu);
37
38                         close(p->sock);
39                         p->sock = 0;
40                         p->state++;
41
42                         pthread_rwlock_unlock(&p->mu);
43                         return NULL;
44                 }
45
46                 // deserialization
47         }
48 }