source: examples/io/simple/server.cfa@ 7215000

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 7215000 was 34d0a28, checked in by Thierry Delisle <tdelisle@…>, 5 years ago

Added example of asynchronous I/O

  • Property mode set to 100644
File size: 2.9 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5#include <unistd.h>
6
7extern "C" {
8 #include <sys/types.h>
9 #include <sys/socket.h>
10 #include <netinet/in.h>
11}
12
13#include <time.hfa>
14#include <thread.hfa>
15
16//----------
17monitor Printer {};
18
19void heartbeat( Printer & mutex ) {
20 fprintf(stderr, ".");
21}
22
23void message( Printer & mutex, char * msg, size_t len ) {
24 fprintf(stderr, "'%.*s'", len, msg);
25}
26
27void status( Printer & mutex, const char * st ) {
28 fprintf(stderr, "%s\n", st);
29}
30
31void error( Printer & mutex, const char * msg, int error) {
32 fprintf(stderr, "%s - %s\n", msg, strerror(error));
33}
34
35Printer printer;
36
37//----------
38thread HeartBeat {};
39
40void ^?{}( HeartBeat & mutex ) {}
41
42void main( HeartBeat & this ) {
43 while(true) {
44 waitfor( ^?{} : this ) { break; }
45 or else{
46 sleep( 5`s );
47 heartbeat( printer );
48 }
49 }
50}
51
52//----------
53extern ssize_t async_recvmsg(int sockfd, struct msghdr *msg, int flags);
54extern int async_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
55extern int async_close(int fd);
56
57//----------
58thread Server { int port; };
59void main( Server & this ) {
60 char data[256];
61 struct iovec iov = { data, 256 };
62 struct msghdr msg = { "", 0, &iov, 1, NULL, 0, 0 };
63
64 int sock = socket(AF_INET, SOCK_STREAM, 0);
65 if(sock < 0) {
66 error( printer, "socket", -sock);
67 exit( EXIT_FAILURE );
68 }
69
70 status( printer, "Socket created" );
71
72 struct sockaddr_in serv_addr;
73 memset(&serv_addr, 0, sizeof(serv_addr));
74 serv_addr.sin_family = AF_INET;
75 serv_addr.sin_addr.s_addr = INADDR_ANY;
76 serv_addr.sin_port = htons(this.port);
77
78 int ret = bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
79 if(ret < 0) {
80 error( printer, "bind", -ret);
81 exit( EXIT_FAILURE );
82 }
83
84 status( printer, "Socket bound" );
85
86 listen(sock,1);
87
88 struct sockaddr_in cli_addr;
89 __socklen_t clilen = sizeof(cli_addr);
90 int newsock = async_accept4(sock, (struct sockaddr *) &cli_addr, &clilen, 0);
91 if (newsock < 0) {
92 error( printer, "accept", -newsock);
93 exit( EXIT_FAILURE );
94 }
95
96 status( printer, "Socket accepted, looping" );
97
98 while(1) {
99 int res = async_recvmsg(newsock, &msg, 0);
100 if(res == 0) break;
101 if(res < 0) {
102 error( printer, "recvmsg", -res);
103 exit( EXIT_FAILURE );
104 }
105
106 message(printer, data, res);
107 }
108
109 ret = async_close(newsock);
110 if(ret < 0) {
111 error( printer, "close new", -ret);
112 exit( EXIT_FAILURE );
113 }
114
115 ret = async_close(sock);
116 if(ret < 0) {
117 error( printer, "close old", -ret);
118 exit( EXIT_FAILURE );
119 }
120}
121
122//----------
123int main(int argc, char * argv []) {
124 if(argc != 2) {
125 printf("usage: %s portnumber\n", argv[0]);
126 exit( EXIT_FAILURE );
127 }
128 int port = atoi(argv[1]);
129 if(port < 1) {
130 printf("Invalid port : %d (from %s)\n", port, argv[1]);
131 exit( EXIT_FAILURE );
132 }
133
134 HeartBeat heartbeat;
135 Server server = { port };
136 // while(true);
137}
Note: See TracBrowser for help on using the repository browser.