1/** \file 2 * \brief Example application using THC stubs and language features 3 */ 4 5/* 6 * Copyright (c) 2010, ETH Zurich. 7 * All rights reserved. 8 * 9 * This file is distributed under the terms in the attached LICENSE file. 10 * If you do not find this file, copies can be found by writing to: 11 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group. 12 */ 13 14#include <stdio.h> 15#include <string.h> 16 17#include <barrelfish/barrelfish.h> 18 19#include <thc/thc.h> 20 21#include <if/xmplthc_defs.h> 22#include <if/xmplthc_thc.h> 23 24const char *service_name = "xmplthc_lang_service"; 25 26/* --------------------- Client ------------------------------ */ 27 28static void run_client(struct xmplthc_thc_client_binding_t *cl, int id) 29{ 30 int i = 42 + id; 31 char *s = NULL; 32 33 while (true) { 34 cl->call_seq.myrpc(cl, i, &s); 35 free(s); 36 } 37 38} 39 40 41static void start_client(char *arg) 42{ 43 errval_t err; 44 45 struct xmplthc_binding *b; 46 struct xmplthc_thc_client_binding_t *cl; 47 48 err = xmplthc_thc_connect_by_name(service_name, 49 get_default_waitset(), 50 IDC_BIND_FLAGS_DEFAULT, 51 &b); 52 if (err_is_fail(err)) { 53 USER_PANIC_ERR(err, "could not bind (thc)"); 54 } 55 56 cl = malloc(sizeof(struct xmplthc_thc_client_binding_t)); 57 assert(cl != NULL); 58 59 err = xmplthc_thc_init_client(cl, b, b); 60 if (err_is_fail(err)) { 61 USER_PANIC_ERR(err, "could not init client (thc)"); 62 } 63 64 run_client(cl, atoi(arg)); 65} 66 67 68/* --------------------- Server ------------------------------ */ 69 70static void rx_xmplthc_myrpc(struct xmplthc_thc_service_binding_t *sv, 71 int i) 72{ 73 debug_printf("received xmplthc_myrpc_call: %d\n", i); 74 75 // send reply 76 char *s = malloc(20); 77 if (s != NULL) { 78 snprintf(s, 20, "!%d!", i); 79 } 80 sv->send.myrpc(sv, s); 81} 82 83 84 85 86static void run_server(struct xmplthc_thc_service_binding_t *sv) 87{ 88 xmplthc_service_msg_t msg; 89 bool loop = true; 90 91 // this is the bitmap of messages we are interested in receiving 92 struct xmplthc_service_selector selector = { 93 .mymsg = 0, 94 .mycall = 0, 95 .myrpc = 1, 96 }; 97 98 while (loop) { 99 // receive any message 100 sv->recv_any(sv, &msg, selector); 101 102 // dispatch it 103 switch(msg.msg) { 104 case xmplthc_myrpc: 105 rx_xmplthc_myrpc(sv, msg.args.myrpc.in.i); 106 break; 107 default: 108 debug_printf("unexpected message: %d\n", msg.msg); 109 loop = false; 110 break; 111 } 112 } 113 114} 115 116 117 118static void start_server(void) 119{ 120 121 errval_t err; 122 123 struct xmplthc_thc_export_info e_info; 124 struct xmplthc_thc_service_binding_t *sv; 125 struct xmplthc_binding *b; 126 iref_t iref; 127 128 err = xmplthc_thc_export(&e_info, service_name, 129 get_default_waitset(), 130 IDC_EXPORT_FLAGS_DEFAULT, 131 &iref); 132 if (err_is_fail(err)) { 133 USER_PANIC_ERR(err, "thc export failed"); 134 } 135 136 do { 137 138 while (true) { 139 140 debug_printf("server: waiting for another connection\n"); 141 142 err = xmplthc_thc_accept(&e_info, &b); 143 if (err_is_fail(err)) { 144 USER_PANIC_ERR(err, "thc accept failed"); 145 } 146 147 sv = malloc(sizeof(struct xmplthc_thc_service_binding_t)); 148 assert(sv != NULL); 149 150 err = xmplthc_thc_init_service(sv, b, b); 151 if (err_is_fail(err)) { 152 USER_PANIC_ERR(err, "thc init failed"); 153 } 154 155 async run_server(sv); 156 } 157 158 } finish; 159} 160 161 162 163/* --------------------- Main ------------------------------ */ 164 165int thcmain(int argc, char *argv[]) 166{ 167 if ((argc >= 2) && (strcmp(argv[1], "client") == 0)) { 168 start_client(argv[2]); 169 } else if ((argc >= 2) && (strcmp(argv[1], "server") == 0)) { 170 start_server(); 171 } else { 172 printf("usage: %s client|server\n", argv[0]); 173 return EXIT_FAILURE; 174 } 175 176 return EXIT_SUCCESS; 177} 178