Changeset bfd1546 in mainline for uspace/srv/ns/ns.c
- Timestamp:
- 2009-02-15T00:01:06Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 08b777e
- Parents:
- 4cac212c
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/ns/ns.c
r4cac212c rbfd1546 41 41 #include <ipc/services.h> 42 42 #include <stdio.h> 43 #include <bool.h> 43 44 #include <unistd.h> 44 45 #include <stdlib.h> … … 48 49 #include <libadt/hash_table.h> 49 50 #include <sysinfo.h> 51 #include <loader/loader.h> 50 52 #include <ddi.h> 51 53 #include <as.h> … … 57 59 static int register_service(ipcarg_t service, ipcarg_t phone, ipc_call_t *call); 58 60 static int connect_to_service(ipcarg_t service, ipc_call_t *call, 61 ipc_callid_t callid); 62 63 void register_clonable(ipcarg_t service, ipcarg_t phone, ipc_call_t *call, 64 ipc_callid_t callid); 65 void connect_to_clonable(ipcarg_t service, ipc_call_t *call, 59 66 ipc_callid_t callid); 60 67 … … 84 91 static void *clockaddr = NULL; 85 92 static void *klogaddr = NULL; 93 94 /** Request for connection to a clonable service. */ 95 typedef struct { 96 link_t link; 97 ipcarg_t service; 98 ipc_call_t *call; 99 ipc_callid_t callid; 100 } cs_req_t; 101 102 /** List of clonable-service connection requests. */ 103 static link_t cs_req; 104 105 /** Return true if @a service is clonable. */ 106 static bool service_clonable(int service) 107 { 108 return service == SERVICE_LOAD; 109 } 86 110 87 111 static void get_as_area(ipc_callid_t callid, ipc_call_t *call, char *name, … … 117 141 return ENOMEM; 118 142 } 143 144 list_initialize(&cs_req); 119 145 120 146 printf(NAME ": Accepting connections\n"); … … 143 169 * Server requests service registration. 144 170 */ 145 retval = register_service(IPC_GET_ARG1(call), 146 IPC_GET_ARG5(call), &call); 171 if (service_clonable(IPC_GET_ARG1(call))) { 172 register_clonable(IPC_GET_ARG1(call), 173 IPC_GET_ARG5(call), &call, callid); 174 continue; 175 } else { 176 retval = register_service(IPC_GET_ARG1(call), 177 IPC_GET_ARG5(call), &call); 178 } 147 179 break; 148 180 case IPC_M_CONNECT_ME_TO: … … 150 182 * Client requests to be connected to a service. 151 183 */ 152 retval = connect_to_service(IPC_GET_ARG1(call), &call, 153 callid); 184 if (service_clonable(IPC_GET_ARG1(call))) { 185 connect_to_clonable(IPC_GET_ARG1(call), 186 &call, callid); 187 continue; 188 } else { 189 retval = connect_to_service(IPC_GET_ARG1(call), 190 &call, callid); 191 } 154 192 break; 155 193 default: … … 168 206 /** Register service. 169 207 * 170 * @param service 171 * @param phone 172 * @param call 173 * 174 * @return 208 * @param service Service to be registered. 209 * @param phone Phone to be used for connections to the service. 210 * @param call Pointer to call structure. 211 * 212 * @return Zero on success or a value from @ref errno.h. 175 213 */ 176 214 int register_service(ipcarg_t service, ipcarg_t phone, ipc_call_t *call) … … 182 220 }; 183 221 hashed_service_t *hs; 184 222 185 223 if (hash_table_find(&ns_hash_table, keys)) { 186 224 return EEXISTS; … … 203 241 /** Connect client to service. 204 242 * 205 * @param service 206 * @param call 207 * @param callid 243 * @param service Service to be connected to. 244 * @param call Pointer to call structure. 245 * @param callid Call ID of the request. 208 246 * 209 247 * @return Zero on success or a value from @ref errno.h. … … 214 252 link_t *hlp; 215 253 hashed_service_t *hs; 216 254 217 255 hlp = hash_table_find(&ns_hash_table, keys); 218 256 if (!hlp) { … … 222 260 return ipc_forward_fast(callid, hs->phone, IPC_GET_ARG2(*call), 223 261 IPC_GET_ARG3(*call), 0, IPC_FF_NONE); 262 } 263 264 /** Register clonable service. 265 * 266 * @param service Service to be registered. 267 * @param phone Phone to be used for connections to the service. 268 * @param call Pointer to call structure. 269 */ 270 void register_clonable(ipcarg_t service, ipcarg_t phone, ipc_call_t *call, 271 ipc_callid_t callid) 272 { 273 int rc; 274 cs_req_t *csr; 275 276 if (list_empty(&cs_req)) { 277 /* There was no pending connection request. */ 278 printf(NAME ": Unexpected clonable server.\n"); 279 ipc_answer_0(callid, EBUSY); 280 return; 281 } 282 283 csr = list_get_instance(cs_req.next, cs_req_t, link); 284 list_remove(&csr->link); 285 286 /* Currently we can only handle a single type of clonable service. */ 287 assert(csr->service == SERVICE_LOAD); 288 289 ipc_answer_0(callid, EOK); 290 291 rc = ipc_forward_fast(csr->callid, phone, IPC_GET_ARG2(*csr->call), 292 IPC_GET_ARG3(*csr->call), 0, IPC_FF_NONE); 293 294 free(csr); 295 } 296 297 /** Connect client to clonable service. 298 * 299 * @param service Service to be connected to. 300 * @param call Pointer to call structure. 301 * @param callid Call ID of the request. 302 * 303 * @return Zero on success or a value from @ref errno.h. 304 */ 305 void connect_to_clonable(ipcarg_t service, ipc_call_t *call, 306 ipc_callid_t callid) 307 { 308 int rc; 309 cs_req_t *csr; 310 311 assert(service == SERVICE_LOAD); 312 313 csr = malloc(sizeof(cs_req_t)); 314 if (csr == NULL) { 315 ipc_answer_0(callid, ENOMEM); 316 return; 317 } 318 319 /* Spawn a loader. */ 320 rc = loader_spawn("loader"); 321 322 if (rc < 0) { 323 free(csr); 324 ipc_answer_0(callid, rc); 325 return; 326 } 327 328 csr->service = service; 329 csr->call = call; 330 csr->callid = callid; 331 332 /* 333 * We can forward the call only after the server we spawned connects 334 * to us. Meanwhile we might need to service more connection requests. 335 * Thus we store the call in a queue. 336 */ 337 list_append(&csr->link, &cs_req); 224 338 } 225 339
Note:
See TracChangeset
for help on using the changeset viewer.