Changeset 42a619b in mainline
- Timestamp:
- 2011-08-19T08:58:50Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 7dcb7981, 903bac0a, c2cf033
- Parents:
- ef7052ec (diff), d894fbd (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 38 edited
Legend:
- Unmodified
- Added
- Removed
-
Makefile
ref7052ec r42a619b 54 54 55 55 cscope: 56 find kernel boot uspace -regex '^.*\.[chsS]$$' | xargs $(CSCOPE) -b -k -u -f$(CSCOPE).out56 find abi kernel boot uspace -regex '^.*\.[chsS]$$' | xargs $(CSCOPE) -b -k -u -f$(CSCOPE).out 57 57 58 58 # Pre-integration build check -
abi/include/ipc/event.h
ref7052ec r42a619b 46 46 } event_type_t; 47 47 48 /** Per-task events. */ 49 typedef enum event_task_type { 50 EVENT_TASK_STATE_CHANGE = EVENT_END, 51 EVENT_TASK_END 52 } event_task_type_t; 53 48 54 #endif 49 55 -
abi/include/ipc/methods.h
ref7052ec r42a619b 171 171 #define IPC_M_DATA_READ 8 172 172 173 /** Authorize change of recipient's state in a third party task. 174 * - ARG1 - user protocol defined data 175 * - ARG2 - user protocol defined data 176 * - ARG3 - user protocol defined data 177 * - ARG5 - sender's phone to the third party task 178 * 179 * on EOK answer, the recipient must set: 180 * 181 * - ARG1 - recipient's phone to the third party task 182 */ 183 #define IPC_M_STATE_CHANGE_AUTHORIZE 9 184 173 185 /** Debug the recipient. 174 186 * - ARG1 - specifies the debug method (from udebug_method_t) … … 176 188 * 177 189 */ 178 #define IPC_M_DEBUG 9190 #define IPC_M_DEBUG 10 179 191 180 192 /** Last system IPC method */ -
kernel/generic/include/console/console.h
ref7052ec r42a619b 63 63 64 64 extern void klog_init(void); 65 extern void klog_update(void );65 extern void klog_update(void *); 66 66 67 67 extern wchar_t getc(indev_t *indev); -
kernel/generic/include/ipc/event.h
ref7052ec r42a619b 41 41 #include <ipc/ipc.h> 42 42 43 typedef void (*event_callback_t)(void); 43 typedef struct task task_t; 44 45 typedef void (*event_callback_t)(void *); 44 46 45 47 /** Event notification structure. */ … … 61 63 62 64 extern void event_init(void); 65 extern void event_task_init(task_t *); 63 66 extern void event_cleanup_answerbox(answerbox_t *); 64 67 extern void event_set_unmask_callback(event_type_t, event_callback_t); 68 extern void event_task_set_unmask_callback(task_t *, event_task_type_t, 69 event_callback_t); 65 70 66 71 #define event_notify_0(e, m) \ … … 77 82 event_notify((e), (m), (a1), (a2), (a3), (a4), (a5)) 78 83 84 #define event_task_notify_0(t, e, m) \ 85 event_task_notify((t), (e), (m), 0, 0, 0, 0, 0) 86 #define event_task_notify_1(t, e, m, a1) \ 87 event_task_notify((t), (e), (m), (a1), 0, 0, 0, 0) 88 #define event_task_notify_2(t, e, m, a1, a2) \ 89 event_task_notify((t), (e), (m), (a1), (a2), 0, 0, 0) 90 #define event_task_notify_3(t, e, m, a1, a2, a3) \ 91 event_task_notify((t), (e), (m), (a1), (a2), (a3), 0, 0) 92 #define event_task_notify_4(t, e, m, a1, a2, a3, a4) \ 93 event_task_notify((t), (e), (m), (a1), (a2), (a3), (a4), 0) 94 #define event_task_notify_5(t, e, m, a1, a2, a3, a4, a5) \ 95 event_task_notify((t), (e), (m), (a1), (a2), (a3), (a4), (a5)) 96 79 97 extern int event_notify(event_type_t, bool, sysarg_t, sysarg_t, sysarg_t, 80 98 sysarg_t, sysarg_t); 99 extern int event_task_notify(task_t *, event_task_type_t, bool, sysarg_t, sysarg_t, 100 sysarg_t, sysarg_t, sysarg_t); 81 101 82 102 extern sysarg_t sys_event_subscribe(sysarg_t, sysarg_t); -
kernel/generic/include/proc/task.h
ref7052ec r42a619b 38 38 #include <cpu.h> 39 39 #include <ipc/ipc.h> 40 #include <ipc/event.h> 41 #include <ipc/kbox.h> 40 42 #include <synch/spinlock.h> 41 43 #include <synch/mutex.h> … … 53 55 #include <proc/scheduler.h> 54 56 #include <udebug/udebug.h> 55 #include <ipc/kbox.h>56 57 #include <mm/as.h> 57 58 #include <abi/sysinfo.h> … … 93 94 phone_t phones[IPC_MAX_PHONES]; 94 95 stats_ipc_t ipc_info; /**< IPC statistics */ 95 /**List of synchronous answerboxes. */96 list_t sync_boxes;96 list_t sync_boxes; /**< List of synchronous answerboxes. */ 97 event_t events[EVENT_TASK_END - EVENT_END]; 97 98 98 99 #ifdef CONFIG_UDEBUG -
kernel/generic/src/console/console.c
ref7052ec r42a619b 248 248 } 249 249 250 void klog_update(void )250 void klog_update(void *e) 251 251 { 252 252 if (!atomic_get(&klog_inited)) … … 327 327 /* Force notification on newline */ 328 328 if (ch == '\n') 329 klog_update( );329 klog_update(NULL); 330 330 } 331 331 … … 358 358 free(data); 359 359 } else 360 klog_update( );360 klog_update(NULL); 361 361 362 362 return size; -
kernel/generic/src/ipc/event.c
ref7052ec r42a619b 40 40 #include <synch/spinlock.h> 41 41 #include <console/console.h> 42 #include <proc/task.h> 42 43 #include <memstr.h> 43 44 #include <errno.h> … … 47 48 static event_t events[EVENT_END]; 48 49 50 static void event_initialize(event_t *event) 51 { 52 spinlock_initialize(&event->lock, "event.lock"); 53 event->answerbox = NULL; 54 event->counter = 0; 55 event->imethod = 0; 56 event->masked = false; 57 event->unmask_callback = NULL; 58 } 59 60 static event_t *evno2event(int evno, task_t *t) 61 { 62 ASSERT(evno < EVENT_TASK_END); 63 64 event_t *event; 65 66 if (evno < EVENT_END) 67 event = &events[(event_type_t) evno]; 68 else 69 event = &t->events[(event_task_type_t) evno - EVENT_END]; 70 71 return event; 72 } 73 49 74 /** Initialize kernel events. 50 75 * … … 52 77 void event_init(void) 53 78 { 54 for (unsigned int i = 0; i < EVENT_END; i++) { 55 spinlock_initialize(&events[i].lock, "event.lock"); 56 events[i].answerbox = NULL; 57 events[i].counter = 0; 58 events[i].imethod = 0; 59 events[i].masked = false; 60 events[i].unmask_callback = NULL; 61 } 62 } 79 for (unsigned int i = 0; i < EVENT_END; i++) 80 event_initialize(evno2event(i, NULL)); 81 } 82 83 void event_task_init(task_t *t) 84 { 85 for (unsigned int i = EVENT_END; i < EVENT_TASK_END; i++) 86 event_initialize(evno2event(i, t)); 87 } 88 63 89 64 90 /** Unsubscribe kernel events associated with an answerbox … … 83 109 } 84 110 111 static void _event_set_unmask_callback(event_t *event, event_callback_t callback) 112 { 113 spinlock_lock(&event->lock); 114 event->unmask_callback = callback; 115 spinlock_unlock(&event->lock); 116 } 117 85 118 /** Define a callback function for the event unmask event. 86 119 * … … 94 127 ASSERT(evno < EVENT_END); 95 128 96 spinlock_lock(&events[evno].lock); 97 events[evno].unmask_callback = callback; 98 spinlock_unlock(&events[evno].lock); 129 _event_set_unmask_callback(evno2event(evno, NULL), callback); 130 } 131 132 void event_task_set_unmask_callback(task_t *t, event_task_type_t evno, 133 event_callback_t callback) 134 { 135 ASSERT(evno >= (int) EVENT_END); 136 ASSERT(evno < EVENT_TASK_END); 137 138 _event_set_unmask_callback(evno2event(evno, t), callback); 139 } 140 141 static int event_enqueue(event_t *event, bool mask, sysarg_t a1, sysarg_t a2, 142 sysarg_t a3, sysarg_t a4, sysarg_t a5) 143 { 144 int res; 145 146 spinlock_lock(&event->lock); 147 148 if (event->answerbox != NULL) { 149 if (!event->masked) { 150 call_t *call = ipc_call_alloc(FRAME_ATOMIC); 151 152 if (call) { 153 call->flags |= IPC_CALL_NOTIF; 154 call->priv = ++event->counter; 155 156 IPC_SET_IMETHOD(call->data, event->imethod); 157 IPC_SET_ARG1(call->data, a1); 158 IPC_SET_ARG2(call->data, a2); 159 IPC_SET_ARG3(call->data, a3); 160 IPC_SET_ARG4(call->data, a4); 161 IPC_SET_ARG5(call->data, a5); 162 163 irq_spinlock_lock(&event->answerbox->irq_lock, true); 164 list_append(&call->link, &event->answerbox->irq_notifs); 165 irq_spinlock_unlock(&event->answerbox->irq_lock, true); 166 167 waitq_wakeup(&event->answerbox->wq, WAKEUP_FIRST); 168 169 if (mask) 170 event->masked = true; 171 172 res = EOK; 173 } else 174 res = ENOMEM; 175 } else 176 res = EBUSY; 177 } else 178 res = ENOENT; 179 180 spinlock_unlock(&event->lock); 181 return res; 99 182 } 100 183 … … 123 206 ASSERT(evno < EVENT_END); 124 207 125 spinlock_lock(&events[evno].lock); 126 127 int ret; 128 129 if (events[evno].answerbox != NULL) { 130 if (!events[evno].masked) { 131 call_t *call = ipc_call_alloc(FRAME_ATOMIC); 132 133 if (call) { 134 call->flags |= IPC_CALL_NOTIF; 135 call->priv = ++events[evno].counter; 136 137 IPC_SET_IMETHOD(call->data, events[evno].imethod); 138 IPC_SET_ARG1(call->data, a1); 139 IPC_SET_ARG2(call->data, a2); 140 IPC_SET_ARG3(call->data, a3); 141 IPC_SET_ARG4(call->data, a4); 142 IPC_SET_ARG5(call->data, a5); 143 144 irq_spinlock_lock(&events[evno].answerbox->irq_lock, true); 145 list_append(&call->link, &events[evno].answerbox->irq_notifs); 146 irq_spinlock_unlock(&events[evno].answerbox->irq_lock, true); 147 148 waitq_wakeup(&events[evno].answerbox->wq, WAKEUP_FIRST); 149 150 if (mask) 151 events[evno].masked = true; 152 153 ret = EOK; 154 } else 155 ret = ENOMEM; 156 } else 157 ret = EBUSY; 158 } else 159 ret = ENOENT; 160 161 spinlock_unlock(&events[evno].lock); 162 163 return ret; 208 return event_enqueue(evno2event(evno, NULL), mask, a1, a2, a3, a4, a5); 209 } 210 211 /** Send per-task kernel notification event 212 * 213 * @param t Destination task. 214 * @param evno Event type. 215 * @param mask Mask further notifications after a successful 216 * sending. 217 * @param a1 First argument. 218 * @param a2 Second argument. 219 * @param a3 Third argument. 220 * @param a4 Fourth argument. 221 * @param a5 Fifth argument. 222 * 223 * @return EOK if notification was successfully sent. 224 * @return ENOMEM if the notification IPC message failed to allocate. 225 * @return EBUSY if the notifications of the given type are 226 * currently masked. 227 * @return ENOENT if the notifications of the given type are 228 * currently not subscribed. 229 * 230 */ 231 int event_task_notify(task_t *t, event_task_type_t evno, bool mask, sysarg_t a1, 232 sysarg_t a2, sysarg_t a3, sysarg_t a4, sysarg_t a5) 233 { 234 ASSERT(evno >= (int) EVENT_END); 235 ASSERT(evno < EVENT_TASK_END); 236 237 return event_enqueue(evno2event(evno, t), mask, a1, a2, a3, a4, a5); 164 238 } 165 239 … … 176 250 * 177 251 */ 178 static int event_subscribe(event_t ype_t evno, sysarg_t imethod,252 static int event_subscribe(event_t *event, sysarg_t imethod, 179 253 answerbox_t *answerbox) 180 254 { 181 ASSERT(evno < EVENT_END);182 183 spinlock_lock(&events[evno].lock);184 185 255 int res; 186 187 if (events[evno].answerbox == NULL) { 188 events[evno].answerbox = answerbox; 189 events[evno].imethod = imethod; 190 events[evno].counter = 0; 191 events[evno].masked = false; 256 257 spinlock_lock(&event->lock); 258 259 if (event->answerbox == NULL) { 260 event->answerbox = answerbox; 261 event->imethod = imethod; 262 event->counter = 0; 263 event->masked = false; 192 264 res = EOK; 193 265 } else 194 266 res = EEXISTS; 195 267 196 spinlock_unlock(&event s[evno].lock);268 spinlock_unlock(&event->lock); 197 269 198 270 return res; … … 204 276 * 205 277 */ 206 static void event_unmask(event_type_t evno) 207 { 208 ASSERT(evno < EVENT_END); 209 210 spinlock_lock(&events[evno].lock); 211 events[evno].masked = false; 212 event_callback_t callback = events[evno].unmask_callback; 213 spinlock_unlock(&events[evno].lock); 278 static void event_unmask(event_t *event) 279 { 280 spinlock_lock(&event->lock); 281 event->masked = false; 282 event_callback_t callback = event->unmask_callback; 283 spinlock_unlock(&event->lock); 214 284 215 285 /* … … 218 288 */ 219 289 if (callback != NULL) 220 callback( );290 callback(event); 221 291 } 222 292 … … 235 305 sysarg_t sys_event_subscribe(sysarg_t evno, sysarg_t imethod) 236 306 { 237 if (evno >= EVENT_ END)307 if (evno >= EVENT_TASK_END) 238 308 return ELIMIT; 239 309 240 return (sysarg_t) event_subscribe( (event_type_t) evno, (sysarg_t)241 imethod, &TASK->answerbox);310 return (sysarg_t) event_subscribe(evno2event(evno, TASK), 311 (sysarg_t) imethod, &TASK->answerbox); 242 312 } 243 313 … … 257 327 sysarg_t sys_event_unmask(sysarg_t evno) 258 328 { 259 if (evno >= EVENT_ END)329 if (evno >= EVENT_TASK_END) 260 330 return ELIMIT; 261 331 262 event_unmask((event_type_t) evno); 332 event_unmask(evno2event(evno, TASK)); 333 263 334 return EOK; 264 335 } -
kernel/generic/src/ipc/sysipc.c
ref7052ec r42a619b 44 44 #include <ipc/irq.h> 45 45 #include <ipc/ipcrsc.h> 46 #include <ipc/event.h> 46 47 #include <ipc/kbox.h> 47 48 #include <synch/waitq.h> … … 134 135 case IPC_M_DATA_WRITE: 135 136 case IPC_M_DATA_READ: 137 case IPC_M_STATE_CHANGE_AUTHORIZE: 136 138 return true; 137 139 default: … … 164 166 case IPC_M_DATA_WRITE: 165 167 case IPC_M_DATA_READ: 168 case IPC_M_STATE_CHANGE_AUTHORIZE: 166 169 return true; 167 170 default: … … 334 337 free(answer->buffer); 335 338 answer->buffer = NULL; 339 } else if (IPC_GET_IMETHOD(*olddata) == IPC_M_STATE_CHANGE_AUTHORIZE) { 340 if (!IPC_GET_RETVAL(answer->data)) { 341 /* The recipient authorized the change of state. */ 342 phone_t *recipient_phone; 343 task_t *other_task_s; 344 task_t *other_task_r; 345 int rc; 346 347 rc = phone_get(IPC_GET_ARG1(answer->data), 348 &recipient_phone); 349 if (rc != EOK) { 350 IPC_SET_RETVAL(answer->data, ENOENT); 351 return ENOENT; 352 } 353 354 mutex_lock(&recipient_phone->lock); 355 if (recipient_phone->state != IPC_PHONE_CONNECTED) { 356 mutex_unlock(&recipient_phone->lock); 357 IPC_SET_RETVAL(answer->data, EINVAL); 358 return EINVAL; 359 } 360 361 other_task_r = recipient_phone->callee->task; 362 other_task_s = (task_t *) IPC_GET_ARG5(*olddata); 363 364 /* 365 * See if both the sender and the recipient meant the 366 * same third party task. 367 */ 368 if (other_task_r != other_task_s) { 369 IPC_SET_RETVAL(answer->data, EINVAL); 370 rc = EINVAL; 371 } else { 372 rc = event_task_notify_5(other_task_r, 373 EVENT_TASK_STATE_CHANGE, false, 374 IPC_GET_ARG1(*olddata), 375 IPC_GET_ARG2(*olddata), 376 IPC_GET_ARG3(*olddata), 377 (sysarg_t) olddata->task, 378 (sysarg_t) TASK); 379 IPC_SET_RETVAL(answer->data, rc); 380 } 381 382 mutex_unlock(&recipient_phone->lock); 383 return rc; 384 } 336 385 } 337 386 … … 456 505 } 457 506 507 break; 508 } 509 case IPC_M_STATE_CHANGE_AUTHORIZE: { 510 phone_t *sender_phone; 511 task_t *other_task_s; 512 513 if (phone_get(IPC_GET_ARG5(call->data), &sender_phone) != EOK) 514 return ENOENT; 515 516 mutex_lock(&sender_phone->lock); 517 if (sender_phone->state != IPC_PHONE_CONNECTED) { 518 mutex_unlock(&sender_phone->lock); 519 return EINVAL; 520 } 521 522 other_task_s = sender_phone->callee->task; 523 524 mutex_unlock(&sender_phone->lock); 525 526 /* Remember the third party task hash. */ 527 IPC_SET_ARG5(call->data, (sysarg_t) other_task_s); 458 528 break; 459 529 } -
kernel/generic/src/proc/task.c
ref7052ec r42a619b 50 50 #include <ipc/ipc.h> 51 51 #include <ipc/ipcrsc.h> 52 #include <ipc/event.h> 52 53 #include <print.h> 53 54 #include <errno.h> … … 57 58 #include <syscall/copy.h> 58 59 #include <macros.h> 59 #include <ipc/event.h>60 60 61 61 /** Spinlock protecting the tasks_tree AVL tree. */ … … 201 201 task->ipc_info.irq_notif_received = 0; 202 202 task->ipc_info.forwarded = 0; 203 204 event_task_init(task); 203 205 204 206 #ifdef CONFIG_UDEBUG -
uspace/app/bdsh/exec.c
ref7052ec r42a619b 40 40 #include <str_error.h> 41 41 #include <errno.h> 42 #include <vfs/vfs.h> 42 43 43 44 #include "config.h" … … 99 100 char *tmp; 100 101 int rc, retval, i; 101 fdi_node_t file_nodes[3];102 fdi_node_t *file_nodes_p[4];102 int file_handles[3]; 103 int *file_handles_p[4]; 103 104 FILE *files[3]; 104 105 … … 111 112 112 113 for (i = 0; i < 3 && files[i] != NULL; i++) { 113 if (f node(files[i], &file_nodes[i]) == EOK) {114 file_ nodes_p[i] = &file_nodes[i];114 if (fhandle(files[i], &file_handles[i]) == EOK) { 115 file_handles_p[i] = &file_handles[i]; 115 116 } 116 117 else { 117 file_ nodes_p[i] = NULL;118 file_handles_p[i] = NULL; 118 119 } 119 120 } 120 file_ nodes_p[i] = NULL;121 file_handles_p[i] = NULL; 121 122 122 rc = task_spawnvf(&tid, tmp, (const char **) argv, file_ nodes_p);123 rc = task_spawnvf(&tid, tmp, (const char **) argv, file_handles_p); 123 124 free(tmp); 124 125 -
uspace/app/trace/trace.c
ref7052ec r42a619b 50 50 #include <sys/types.h> 51 51 #include <sys/typefmt.h> 52 #include <vfs/vfs.h> 52 53 53 54 #include <libc.h> … … 586 587 587 588 /* Send default files */ 588 fdi_node_t *files[4];589 fdi_node_t stdin_node;590 fdi_node_t stdout_node;591 fdi_node_t stderr_node;592 593 if ((stdin != NULL) && (f node(stdin, &stdin_node) == EOK))594 files[0] = & stdin_node;589 int *files[4]; 590 int fd_stdin; 591 int fd_stdout; 592 int fd_stderr; 593 594 if ((stdin != NULL) && (fhandle(stdin, &fd_stdin) == EOK)) 595 files[0] = &fd_stdin; 595 596 else 596 597 files[0] = NULL; 597 598 598 if ((stdout != NULL) && (f node(stdout, &stdout_node) == EOK))599 files[1] = & stdout_node;599 if ((stdout != NULL) && (fhandle(stdout, &fd_stdout) == EOK)) 600 files[1] = &fd_stdout; 600 601 else 601 602 files[1] = NULL; 602 603 603 if ((stderr != NULL) && (f node(stderr, &stderr_node) == EOK))604 files[2] = & stderr_node;604 if ((stderr != NULL) && (fhandle(stderr, &fd_stderr) == EOK)) 605 files[2] = &fd_stderr; 605 606 else 606 607 files[2] = NULL; … … 761 762 o = oper_new("open", 2, arg_def, V_INT_ERRNO, 0, resp_def); 762 763 proto_add_oper(p, VFS_IN_OPEN, o); 763 o = oper_new("open_node", 4, arg_def, V_INT_ERRNO, 0, resp_def);764 proto_add_oper(p, VFS_IN_OPEN_NODE, o);765 764 o = oper_new("read", 1, arg_def, V_ERRNO, 1, resp_def); 766 765 proto_add_oper(p, VFS_IN_READ, o); -
uspace/lib/c/generic/async.c
ref7052ec r42a619b 201 201 { 202 202 async_client_data_destroy = dtor; 203 }204 205 void *async_get_client_data(void)206 {207 assert(fibril_connection);208 return fibril_connection->client->data;209 203 } 210 204 … … 580 574 } 581 575 576 static client_t *async_client_get(sysarg_t client_hash, bool create) 577 { 578 unsigned long key = client_hash; 579 client_t *client = NULL; 580 581 futex_down(&async_futex); 582 link_t *lnk = hash_table_find(&client_hash_table, &key); 583 if (lnk) { 584 client = hash_table_get_instance(lnk, client_t, link); 585 atomic_inc(&client->refcnt); 586 } else if (create) { 587 client = malloc(sizeof(client_t)); 588 if (client) { 589 client->in_task_hash = client_hash; 590 client->data = async_client_data_create(); 591 592 atomic_set(&client->refcnt, 1); 593 hash_table_insert(&client_hash_table, &key, &client->link); 594 } 595 } 596 597 futex_up(&async_futex); 598 return client; 599 } 600 601 static void async_client_put(client_t *client) 602 { 603 bool destroy; 604 unsigned long key = client->in_task_hash; 605 606 futex_down(&async_futex); 607 608 if (atomic_predec(&client->refcnt) == 0) { 609 hash_table_remove(&client_hash_table, &key, 1); 610 destroy = true; 611 } else 612 destroy = false; 613 614 futex_up(&async_futex); 615 616 if (destroy) { 617 if (client->data) 618 async_client_data_destroy(client->data); 619 620 free(client); 621 } 622 } 623 624 void *async_get_client_data(void) 625 { 626 assert(fibril_connection); 627 return fibril_connection->client->data; 628 } 629 630 void *async_get_client_data_by_hash(sysarg_t client_hash) 631 { 632 client_t *client = async_client_get(client_hash, false); 633 if (!client) 634 return NULL; 635 if (!client->data) { 636 async_client_put(client); 637 return NULL; 638 } 639 640 return client->data; 641 } 642 643 void async_put_client_data_by_hash(sysarg_t client_hash) 644 { 645 client_t *client = async_client_get(client_hash, false); 646 647 assert(client); 648 assert(client->data); 649 650 /* Drop the reference we got in async_get_client_data_by_hash(). */ 651 async_client_put(client); 652 653 /* Drop our own reference we got at the beginning of this function. */ 654 async_client_put(client); 655 } 656 582 657 /** Wrapper for client connection fibril. 583 658 * … … 598 673 */ 599 674 fibril_connection = (connection_t *) arg; 600 601 futex_down(&async_futex);602 675 603 676 /* … … 606 679 * hash in a new tracking structure. 607 680 */ 608 609 unsigned long key = fibril_connection->in_task_hash; 610 link_t *lnk = hash_table_find(&client_hash_table, &key); 611 612 client_t *client; 613 614 if (lnk) { 615 client = hash_table_get_instance(lnk, client_t, link); 616 atomic_inc(&client->refcnt); 617 } else { 618 client = malloc(sizeof(client_t)); 619 if (!client) { 620 ipc_answer_0(fibril_connection->callid, ENOMEM); 621 futex_up(&async_futex); 622 return 0; 623 } 624 625 client->in_task_hash = fibril_connection->in_task_hash; 626 client->data = async_client_data_create(); 627 628 atomic_set(&client->refcnt, 1); 629 hash_table_insert(&client_hash_table, &key, &client->link); 630 } 631 632 futex_up(&async_futex); 633 681 682 client_t *client = async_client_get(fibril_connection->in_task_hash, true); 683 if (!client) { 684 ipc_answer_0(fibril_connection->callid, ENOMEM); 685 return 0; 686 } 687 634 688 fibril_connection->client = client; 635 689 … … 643 697 * Remove the reference for this client task connection. 644 698 */ 645 bool destroy; 646 647 futex_down(&async_futex); 648 649 if (atomic_predec(&client->refcnt) == 0) { 650 hash_table_remove(&client_hash_table, &key, 1); 651 destroy = true; 652 } else 653 destroy = false; 654 655 futex_up(&async_futex); 656 657 if (destroy) { 658 if (client->data) 659 async_client_data_destroy(client->data); 660 661 free(client); 662 } 699 async_client_put(client); 663 700 664 701 /* … … 666 703 */ 667 704 futex_down(&async_futex); 668 key = fibril_connection->in_phone_hash;705 unsigned long key = fibril_connection->in_phone_hash; 669 706 hash_table_remove(&conn_hash_table, &key, 1); 670 707 futex_up(&async_futex); … … 2429 2466 } 2430 2467 2468 int async_state_change_start(async_exch_t *exch, sysarg_t arg1, sysarg_t arg2, 2469 sysarg_t arg3, async_exch_t *other_exch) 2470 { 2471 return async_req_5_0(exch, IPC_M_STATE_CHANGE_AUTHORIZE, 2472 arg1, arg2, arg3, 0, other_exch->phone); 2473 } 2474 2475 bool async_state_change_receive(ipc_callid_t *callid, sysarg_t *arg1, 2476 sysarg_t *arg2, sysarg_t *arg3) 2477 { 2478 assert(callid); 2479 2480 ipc_call_t call; 2481 *callid = async_get_call(&call); 2482 2483 if (IPC_GET_IMETHOD(call) != IPC_M_STATE_CHANGE_AUTHORIZE) 2484 return false; 2485 2486 if (arg1) 2487 *arg1 = IPC_GET_ARG1(call); 2488 if (arg2) 2489 *arg2 = IPC_GET_ARG2(call); 2490 if (arg3) 2491 *arg3 = IPC_GET_ARG3(call); 2492 2493 return true; 2494 } 2495 2496 int async_state_change_finalize(ipc_callid_t callid, async_exch_t *other_exch) 2497 { 2498 return ipc_answer_1(callid, EOK, other_exch->phone); 2499 } 2500 2431 2501 /** @} 2432 2502 */ -
uspace/lib/c/generic/event.c
ref7052ec r42a619b 54 54 } 55 55 56 int event_task_subscribe(event_task_type_t evno, sysarg_t imethod) 57 { 58 return __SYSCALL2(SYS_EVENT_SUBSCRIBE, (sysarg_t) evno, 59 (sysarg_t) imethod); 60 } 61 56 62 /** Unmask event notifications. 57 63 * … … 66 72 } 67 73 74 int event_task_unmask(event_task_type_t evno) 75 { 76 return __SYSCALL1(SYS_EVENT_UNMASK, (sysarg_t) evno); 77 } 78 68 79 /** @} 69 80 */ -
uspace/lib/c/generic/io/io.c
ref7052ec r42a619b 101 101 static LIST_INITIALIZE(files); 102 102 103 void __stdio_init(int filc , fdi_node_t *filv[])103 void __stdio_init(int filc) 104 104 { 105 105 if (filc > 0) { 106 stdin = f open_node(filv[0], "r");106 stdin = fdopen(0, "r"); 107 107 } else { 108 108 stdin = &stdin_null; … … 111 111 112 112 if (filc > 1) { 113 stdout = f open_node(filv[1], "w");113 stdout = fdopen(1, "w"); 114 114 } else { 115 115 stdout = &stdout_klog; … … 118 118 119 119 if (filc > 2) { 120 stderr = f open_node(filv[2], "w");120 stderr = fdopen(2, "w"); 121 121 } else { 122 122 stderr = &stderr_klog; … … 285 285 } 286 286 287 FILE *fopen_node(fdi_node_t *node, const char *mode)288 {289 int flags;290 if (!parse_mode(mode, &flags))291 return NULL;292 293 /* Open file. */294 FILE *stream = malloc(sizeof(FILE));295 if (stream == NULL) {296 errno = ENOMEM;297 return NULL;298 }299 300 stream->fd = open_node(node, flags);301 if (stream->fd < 0) {302 /* errno was set by open_node() */303 free(stream);304 return NULL;305 }306 307 stream->error = false;308 stream->eof = false;309 stream->klog = false;310 stream->sess = NULL;311 stream->need_sync = false;312 _setvbuf(stream);313 314 list_append(&stream->link, &files);315 316 return stream;317 }318 319 287 int fclose(FILE *stream) 320 288 { … … 780 748 } 781 749 782 int fnode(FILE *stream, fdi_node_t *node) 783 { 784 if (stream->fd >= 0) 785 return fd_node(stream->fd, node); 750 int fhandle(FILE *stream, int *handle) 751 { 752 if (stream->fd >= 0) { 753 *handle = stream->fd; 754 return EOK; 755 } 786 756 787 757 return ENOENT; -
uspace/lib/c/generic/libc.c
ref7052ec r42a619b 91 91 argc = 0; 92 92 argv = NULL; 93 __stdio_init(0 , NULL);93 __stdio_init(0); 94 94 } else { 95 95 argc = __pcb->argc; 96 96 argv = __pcb->argv; 97 __stdio_init(__pcb->filc , __pcb->filv);97 __stdio_init(__pcb->filc); 98 98 (void) chdir(__pcb->cwd); 99 99 } -
uspace/lib/c/generic/loader.c
ref7052ec r42a619b 256 256 * 257 257 */ 258 int loader_set_files(loader_t *ldr, fdi_node_t *const files[]) 259 { 260 /* 261 * Serialize the arguments into a single array. First 262 * compute size of the buffer needed. 263 */ 264 fdi_node_t *const *ap = files; 265 size_t count = 0; 266 while (*ap != NULL) { 267 count++; 268 ap++; 269 } 270 271 fdi_node_t *files_buf; 272 files_buf = (fdi_node_t *) malloc(count * sizeof(fdi_node_t)); 273 if (files_buf == NULL) 274 return ENOMEM; 275 276 /* Fill the buffer */ 277 size_t i; 278 for (i = 0; i < count; i++) 279 files_buf[i] = *files[i]; 280 258 int loader_set_files(loader_t *ldr, int * const files[]) 259 { 281 260 /* Send serialized files to the loader */ 282 261 async_exch_t *exch = async_exchange_begin(ldr->sess); 283 284 ipc_call_t answer; 285 aid_t req = async_send_0(exch, LOADER_SET_FILES, &answer); 286 sysarg_t rc = async_data_write_start(exch, (void *) files_buf, 287 count * sizeof(fdi_node_t)); 288 289 async_exchange_end(exch); 290 free(files_buf); 291 262 async_exch_t *vfs_exch = vfs_exchange_begin(); 263 264 int i; 265 for (i = 0; files[i]; i++) 266 ; 267 268 ipc_call_t answer; 269 aid_t req = async_send_1(exch, LOADER_SET_FILES, i, &answer); 270 271 sysarg_t rc = EOK; 272 273 for (i = 0; files[i]; i++) { 274 rc = async_state_change_start(exch, VFS_PASS_HANDLE, *files[i], 275 0, vfs_exch); 276 if (rc != EOK) 277 break; 278 } 279 280 vfs_exchange_end(vfs_exch); 281 async_exchange_end(exch); 282 292 283 if (rc != EOK) { 293 284 async_wait_for(req, NULL); -
uspace/lib/c/generic/private/async.h
ref7052ec r42a619b 36 36 #define LIBC_PRIVATE_ASYNC_H_ 37 37 38 #include <ipc/common.h> 38 39 #include <adt/list.h> 39 40 #include <fibril.h> -
uspace/lib/c/generic/private/io.h
ref7052ec r42a619b 36 36 #define LIBC_PRIVATE_IO_H_ 37 37 38 #include <vfs/vfs.h> 39 40 extern void __stdio_init(int filc, fdi_node_t *filv[]); 38 extern void __stdio_init(int); 41 39 extern void __stdio_done(void); 42 40 -
uspace/lib/c/generic/task.c
ref7052ec r42a619b 46 46 #include <libc.h> 47 47 #include "private/ns.h" 48 #include <vfs/vfs.h> 48 49 49 50 task_id_t task_get_id(void) … … 102 103 { 103 104 /* Send default files */ 104 fdi_node_t *files[4];105 fdi_node_t stdin_node;106 fdi_node_t stdout_node;107 fdi_node_t stderr_node;108 109 if ((stdin != NULL) && (f node(stdin, &stdin_node) == EOK))110 files[0] = & stdin_node;105 int *files[4]; 106 int fd_stdin; 107 int fd_stdout; 108 int fd_stderr; 109 110 if ((stdin != NULL) && (fhandle(stdin, &fd_stdin) == EOK)) 111 files[0] = &fd_stdin; 111 112 else 112 113 files[0] = NULL; 113 114 114 if ((stdout != NULL) && (f node(stdout, &stdout_node) == EOK))115 files[1] = & stdout_node;115 if ((stdout != NULL) && (fhandle(stdout, &fd_stdout) == EOK)) 116 files[1] = &fd_stdout; 116 117 else 117 118 files[1] = NULL; 118 119 119 if ((stderr != NULL) && (f node(stderr, &stderr_node) == EOK))120 files[2] = & stderr_node;120 if ((stderr != NULL) && (fhandle(stderr, &fd_stderr) == EOK)) 121 files[2] = &fd_stderr; 121 122 else 122 123 files[2] = NULL; … … 142 143 */ 143 144 int task_spawnvf(task_id_t *id, const char *path, const char *const args[], 144 fdi_node_t *const files[])145 int *const files[]) 145 146 { 146 147 /* Connect to a program loader. */ -
uspace/lib/c/generic/vfs/vfs.c
ref7052ec r42a619b 69 69 * 70 70 */ 71 staticasync_exch_t *vfs_exchange_begin(void)71 async_exch_t *vfs_exchange_begin(void) 72 72 { 73 73 fibril_mutex_lock(&vfs_mutex); … … 87 87 * 88 88 */ 89 staticvoid vfs_exchange_end(async_exch_t *exch)89 void vfs_exchange_end(async_exch_t *exch) 90 90 { 91 91 async_exchange_end(exch); … … 329 329 } 330 330 331 int open_node(fdi_node_t *node, int oflag)332 {333 async_exch_t *exch = vfs_exchange_begin();334 335 ipc_call_t answer;336 aid_t req = async_send_4(exch, VFS_IN_OPEN_NODE, node->fs_handle,337 node->service_id, node->index, oflag, &answer);338 339 vfs_exchange_end(exch);340 341 sysarg_t rc;342 async_wait_for(req, &rc);343 344 if (rc != EOK)345 return (int) rc;346 347 return (int) IPC_GET_ARG1(answer);348 }349 350 331 int close(int fildes) 351 332 { … … 819 800 } 820 801 821 int fd_node(int fildes, fdi_node_t *node)822 {823 struct stat stat;824 int rc = fstat(fildes, &stat);825 826 if (rc == EOK) {827 node->fs_handle = stat.fs_handle;828 node->service_id = stat.service_id;829 node->index = stat.index;830 }831 832 return rc;833 }834 835 802 int dup2(int oldfd, int newfd) 836 803 { … … 848 815 } 849 816 817 int fd_wait(void) 818 { 819 async_exch_t *exch = vfs_exchange_begin(); 820 821 sysarg_t ret; 822 sysarg_t rc = async_req_0_1(exch, VFS_IN_WAIT_HANDLE, &ret); 823 824 vfs_exchange_end(exch); 825 826 if (rc == EOK) 827 return (int) ret; 828 829 return (int) rc; 830 } 831 850 832 /** @} 851 833 */ -
uspace/lib/c/include/async.h
ref7052ec r42a619b 186 186 extern void async_set_client_data_destructor(async_client_data_dtor_t); 187 187 extern void *async_get_client_data(void); 188 extern void *async_get_client_data_by_hash(sysarg_t); 189 extern void async_put_client_data_by_hash(sysarg_t); 188 190 189 191 extern void async_set_client_connection(async_client_conn_t); … … 477 479 extern async_sess_t *async_callback_receive_start(exch_mgmt_t, ipc_call_t *); 478 480 481 extern int async_state_change_start(async_exch_t *, sysarg_t, sysarg_t, 482 sysarg_t, async_exch_t *); 483 extern bool async_state_change_receive(ipc_callid_t *, sysarg_t *, sysarg_t *, 484 sysarg_t *); 485 extern int async_state_change_finalize(ipc_callid_t, async_exch_t *); 486 479 487 #endif 480 488 -
uspace/lib/c/include/event.h
ref7052ec r42a619b 37 37 38 38 #include <abi/ipc/event.h> 39 #include <libarch/types.h> 39 40 40 41 extern int event_subscribe(event_type_t, sysarg_t); 42 extern int event_task_subscribe(event_task_type_t, sysarg_t); 41 43 extern int event_unmask(event_type_t); 44 extern int event_task_unmask(event_task_type_t); 42 45 43 46 #endif -
uspace/lib/c/include/ipc/vfs.h
ref7052ec r42a619b 62 62 typedef enum { 63 63 VFS_IN_OPEN = IPC_FIRST_USER_METHOD, 64 VFS_IN_OPEN_NODE,65 64 VFS_IN_READ, 66 65 VFS_IN_WRITE, … … 78 77 VFS_IN_RENAME, 79 78 VFS_IN_STAT, 80 VFS_IN_DUP 79 VFS_IN_DUP, 80 VFS_IN_WAIT_HANDLE, 81 81 } vfs_in_request_t; 82 82 -
uspace/lib/c/include/loader/loader.h
ref7052ec r42a619b 38 38 39 39 #include <task.h> 40 #include <vfs/vfs.h>41 40 42 41 /** Forward declararion */ … … 50 49 extern int loader_set_pathname(loader_t *, const char *); 51 50 extern int loader_set_args(loader_t *, const char *const[]); 52 extern int loader_set_files(loader_t *, fdi_node_t *const[]);51 extern int loader_set_files(loader_t *, int *const[]); 53 52 extern int loader_load_program(loader_t *); 54 53 extern int loader_run(loader_t *); -
uspace/lib/c/include/loader/pcb.h
ref7052ec r42a619b 38 38 39 39 #include <sys/types.h> 40 #include <vfs/vfs.h>41 40 42 41 typedef void (*entry_point_t)(void); … … 62 61 63 62 /** Number of preset files. */ 64 int filc; 65 /** Preset files. */ 66 fdi_node_t **filv; 63 unsigned int filc; 67 64 68 65 /* -
uspace/lib/c/include/task.h
ref7052ec r42a619b 37 37 38 38 #include <sys/types.h> 39 #include <vfs/vfs.h>40 39 41 40 typedef uint64_t task_id_t; … … 53 52 extern int task_spawnv(task_id_t *, const char *path, const char *const []); 54 53 extern int task_spawnvf(task_id_t *, const char *path, const char *const [], 55 fdi_node_t *const []);54 int *const []); 56 55 extern int task_spawnl(task_id_t *, const char *path, ...); 57 56 -
uspace/lib/c/include/vfs/vfs.h
ref7052ec r42a619b 40 40 #include <ipc/loc.h> 41 41 #include <stdio.h> 42 #include <async.h> 42 43 43 /** Libc version of the VFS triplet. 44 * 45 * Unique identification of a file system node 46 * within a file system instance. 47 * 48 */ 49 typedef struct { 50 fs_handle_t fs_handle; 51 service_id_t service_id; 52 fs_index_t index; 53 } fdi_node_t; 44 enum vfs_change_state_type { 45 VFS_PASS_HANDLE 46 }; 54 47 55 48 extern char *absolutize(const char *, size_t *); … … 59 52 extern int unmount(const char *); 60 53 61 extern int open_node(fdi_node_t *, int); 62 extern int fd_node(int, fdi_node_t *); 54 extern int fhandle(FILE *, int *); 63 55 64 extern FILE *fopen_node(fdi_node_t *, const char *); 65 extern int fnode(FILE *, fdi_node_t *); 56 extern int fd_wait(void); 57 58 extern async_exch_t *vfs_exchange_begin(void); 59 extern void vfs_exchange_end(async_exch_t *); 66 60 67 61 #endif -
uspace/srv/hid/input/port/adb_mouse.c
ref7052ec r42a619b 42 42 #include <errno.h> 43 43 #include <loc.h> 44 #include <stdio.h> 44 45 45 46 static mouse_dev_t *mouse_dev; -
uspace/srv/hw/irc/apic/apic.c
ref7052ec r42a619b 45 45 #include <errno.h> 46 46 #include <async.h> 47 #include <stdio.h> 47 48 48 49 #define NAME "apic" -
uspace/srv/loader/main.c
ref7052ec r42a619b 61 61 #include <elf/elf.h> 62 62 #include <elf/elf_load.h> 63 #include <vfs/vfs.h> 63 64 64 65 #ifdef CONFIG_RTLD … … 89 90 90 91 /** Number of preset files */ 91 static int filc = 0; 92 /** Preset files vector */ 93 static fdi_node_t **filv = NULL; 94 /** Buffer holding all preset files */ 95 static fdi_node_t *fil_buf = NULL; 92 static unsigned int filc = 0; 96 93 97 94 static elf_info_t prog_info; … … 239 236 static void ldr_set_files(ipc_callid_t rid, ipc_call_t *request) 240 237 { 241 fdi_node_t *buf; 242 size_t buf_size; 243 int rc = async_data_write_accept((void **) &buf, false, 0, 0, 244 sizeof(fdi_node_t), &buf_size); 245 246 if (rc == EOK) { 247 int count = buf_size / sizeof(fdi_node_t); 248 249 /* 250 * Allocate new filv 251 */ 252 fdi_node_t **_filv = (fdi_node_t **) calloc(count + 1, sizeof(fdi_node_t *)); 253 if (_filv == NULL) { 254 free(buf); 255 async_answer_0(rid, ENOMEM); 256 return; 238 size_t count = IPC_GET_ARG1(*request); 239 240 async_exch_t *vfs_exch = vfs_exchange_begin(); 241 242 for (filc = 0; filc < count; filc++) { 243 ipc_callid_t callid; 244 int fd; 245 246 if (!async_state_change_receive(&callid, NULL, NULL, NULL)) { 247 async_answer_0(callid, EINVAL); 248 break; 257 249 } 258 259 /* 260 * Fill the new filv with argument pointers 261 */ 262 int i; 263 for (i = 0; i < count; i++) 264 _filv[i] = &buf[i]; 265 266 _filv[count] = NULL; 267 268 /* 269 * Copy temporary data to global variables 270 */ 271 if (fil_buf != NULL) 272 free(fil_buf); 273 274 if (filv != NULL) 275 free(filv); 276 277 filc = count; 278 fil_buf = buf; 279 filv = _filv; 280 } 281 250 async_state_change_finalize(callid, vfs_exch); 251 fd = fd_wait(); 252 assert(fd == (int) filc); 253 } 254 255 vfs_exchange_end(vfs_exch); 256 282 257 async_answer_0(rid, EOK); 283 258 } … … 308 283 309 284 pcb.filc = filc; 310 pcb.filv = filv;311 285 312 286 if (prog_info.interp == NULL) { -
uspace/srv/loc/loc.h
ref7052ec r42a619b 36 36 #define LOC_H_ 37 37 38 #include <ipc/loc.h> 38 39 #include <async.h> 39 40 #include <fibril_synch.h> -
uspace/srv/vfs/vfs.c
ref7052ec r42a619b 37 37 38 38 #include <ipc/services.h> 39 #include <abi/ipc/event.h> 40 #include <event.h> 39 41 #include <ns.h> 40 42 #include <async.h> … … 45 47 #include <as.h> 46 48 #include <atomic.h> 49 #include <vfs/vfs.h> 47 50 #include "vfs.h" 48 51 … … 80 83 vfs_open(callid, &call); 81 84 break; 82 case VFS_IN_OPEN_NODE:83 vfs_open_node(callid, &call);84 break;85 85 case VFS_IN_CLOSE: 86 86 vfs_close(callid, &call); … … 118 118 case VFS_IN_DUP: 119 119 vfs_dup(callid, &call); 120 break; 121 case VFS_IN_WAIT_HANDLE: 122 vfs_wait_handle(callid, &call); 123 break; 120 124 default: 121 125 async_answer_0(callid, ENOTSUP); … … 128 132 * connection fibril terminates. 129 133 */ 134 } 135 136 enum { 137 VFS_TASK_STATE_CHANGE 138 }; 139 140 static void notification_received(ipc_callid_t callid, ipc_call_t *call) 141 { 142 switch (IPC_GET_IMETHOD(*call)) { 143 case VFS_TASK_STATE_CHANGE: 144 if (IPC_GET_ARG1(*call) == VFS_PASS_HANDLE) 145 vfs_pass_handle(IPC_GET_ARG4(*call), 146 IPC_GET_ARG5(*call), (int) IPC_GET_ARG2(*call)); 147 break; 148 default: 149 break; 150 } 130 151 } 131 152 … … 170 191 171 192 /* 193 * Set notification handler and subscribe to notifications. 194 */ 195 async_set_interrupt_received(notification_received); 196 event_task_subscribe(EVENT_TASK_STATE_CHANGE, VFS_TASK_STATE_CHANGE); 197 198 /* 172 199 * Register at the naming service. 173 200 */ -
uspace/srv/vfs/vfs.h
ref7052ec r42a619b 175 175 extern int vfs_lookup_internal(char *, int, vfs_lookup_res_t *, 176 176 vfs_pair_t *, ...); 177 extern int vfs_open_node_internal(vfs_lookup_res_t *);178 177 179 178 extern bool vfs_nodes_init(void); … … 189 188 extern void vfs_client_data_destroy(void *); 190 189 190 extern void vfs_pass_handle(sysarg_t, sysarg_t, int); 191 extern int vfs_wait_handle_internal(void); 192 191 193 extern vfs_file_t *vfs_file_get(int); 192 194 extern void vfs_file_put(vfs_file_t *); … … 197 199 extern void vfs_node_addref(vfs_node_t *); 198 200 extern void vfs_node_delref(vfs_node_t *); 201 extern int vfs_open_node_remote(vfs_node_t *); 199 202 200 203 extern void vfs_register(ipc_callid_t, ipc_call_t *); … … 202 205 extern void vfs_unmount(ipc_callid_t, ipc_call_t *); 203 206 extern void vfs_open(ipc_callid_t, ipc_call_t *); 204 extern void vfs_open_node(ipc_callid_t, ipc_call_t *);205 207 extern void vfs_sync(ipc_callid_t, ipc_call_t *); 206 208 extern void vfs_dup(ipc_callid_t, ipc_call_t *); … … 215 217 extern void vfs_unlink(ipc_callid_t, ipc_call_t *); 216 218 extern void vfs_rename(ipc_callid_t, ipc_call_t *); 219 extern void vfs_wait_handle(ipc_callid_t, ipc_call_t *); 217 220 218 221 #endif -
uspace/srv/vfs/vfs_file.c
ref7052ec r42a619b 43 43 #include <fibril.h> 44 44 #include <fibril_synch.h> 45 #include <adt/list.h> 45 46 #include "vfs.h" 46 47 … … 50 51 typedef struct { 51 52 fibril_mutex_t lock; 53 fibril_condvar_t cv; 54 list_t passed_handles; 52 55 vfs_file_t **files; 53 56 } vfs_client_data_t; 54 57 58 typedef struct { 59 link_t link; 60 int handle; 61 } vfs_boxed_handle_t; 62 63 static int _vfs_fd_free(vfs_client_data_t *, int); 64 55 65 /** Initialize the table of open files. */ 56 static bool vfs_files_init(v oid)57 { 58 fibril_mutex_lock(& VFS_DATA->lock);59 if (! FILES) {60 FILES= malloc(MAX_OPEN_FILES * sizeof(vfs_file_t *));61 if (! FILES) {62 fibril_mutex_unlock(& VFS_DATA->lock);66 static bool vfs_files_init(vfs_client_data_t *vfs_data) 67 { 68 fibril_mutex_lock(&vfs_data->lock); 69 if (!vfs_data->files) { 70 vfs_data->files = malloc(MAX_OPEN_FILES * sizeof(vfs_file_t *)); 71 if (!vfs_data->files) { 72 fibril_mutex_unlock(&vfs_data->lock); 63 73 return false; 64 74 } 65 memset( FILES, 0, MAX_OPEN_FILES * sizeof(vfs_file_t *));66 } 67 fibril_mutex_unlock(& VFS_DATA->lock);75 memset(vfs_data->files, 0, MAX_OPEN_FILES * sizeof(vfs_file_t *)); 76 } 77 fibril_mutex_unlock(&vfs_data->lock); 68 78 return true; 69 79 } 70 80 71 81 /** Cleanup the table of open files. */ 72 static void vfs_files_done(v oid)82 static void vfs_files_done(vfs_client_data_t *vfs_data) 73 83 { 74 84 int i; 75 85 76 if (! FILES)86 if (!vfs_data->files) 77 87 return; 78 88 79 89 for (i = 0; i < MAX_OPEN_FILES; i++) { 80 if (FILES[i]) { 81 (void) vfs_fd_free(i); 82 } 83 } 84 85 free(FILES); 90 if (vfs_data->files[i]) 91 (void) _vfs_fd_free(vfs_data, i); 92 } 93 94 free(vfs_data->files); 95 96 while (!list_empty(&vfs_data->passed_handles)) { 97 link_t *lnk; 98 vfs_boxed_handle_t *bh; 99 100 lnk = list_first(&vfs_data->passed_handles); 101 list_remove(lnk); 102 103 bh = list_get_instance(lnk, vfs_boxed_handle_t, link); 104 free(bh); 105 } 86 106 } 87 107 … … 93 113 if (vfs_data) { 94 114 fibril_mutex_initialize(&vfs_data->lock); 115 fibril_condvar_initialize(&vfs_data->cv); 116 list_initialize(&vfs_data->passed_handles); 95 117 vfs_data->files = NULL; 96 118 } … … 103 125 vfs_client_data_t *vfs_data = (vfs_client_data_t *) data; 104 126 105 vfs_files_done( );127 vfs_files_done(vfs_data); 106 128 free(vfs_data); 107 129 } … … 131 153 * incremented. 132 154 */ 133 static void vfs_file_addref(vfs_ file_t *file)134 { 135 assert(fibril_mutex_is_locked(& VFS_DATA->lock));155 static void vfs_file_addref(vfs_client_data_t *vfs_data, vfs_file_t *file) 156 { 157 assert(fibril_mutex_is_locked(&vfs_data->lock)); 136 158 137 159 file->refcnt++; … … 143 165 * decremented. 144 166 */ 145 static int vfs_file_delref(vfs_ file_t *file)167 static int vfs_file_delref(vfs_client_data_t *vfs_data, vfs_file_t *file) 146 168 { 147 169 int rc = EOK; 148 170 149 assert(fibril_mutex_is_locked(& VFS_DATA->lock));171 assert(fibril_mutex_is_locked(&vfs_data->lock)); 150 172 151 173 if (file->refcnt-- == 1) { … … 162 184 } 163 185 164 165 /** Allocate a file descriptor. 166 * 167 * @param desc If true, look for an available file descriptor 168 * in a descending order. 169 * 170 * @return First available file descriptor or a negative error 171 * code. 172 */ 173 int vfs_fd_alloc(bool desc) 174 { 175 if (!vfs_files_init()) 186 static int _vfs_fd_alloc(vfs_client_data_t *vfs_data, bool desc) 187 { 188 if (!vfs_files_init(vfs_data)) 176 189 return ENOMEM; 177 190 … … 182 195 i = 0; 183 196 184 fibril_mutex_lock(& VFS_DATA->lock);197 fibril_mutex_lock(&vfs_data->lock); 185 198 while (true) { 186 if (! FILES[i]) {187 FILES[i] = (vfs_file_t *) malloc(sizeof(vfs_file_t));188 if (! FILES[i]) {189 fibril_mutex_unlock(& VFS_DATA->lock);199 if (!vfs_data->files[i]) { 200 vfs_data->files[i] = (vfs_file_t *) malloc(sizeof(vfs_file_t)); 201 if (!vfs_data->files[i]) { 202 fibril_mutex_unlock(&vfs_data->lock); 190 203 return ENOMEM; 191 204 } 192 205 193 memset( FILES[i], 0, sizeof(vfs_file_t));194 fibril_mutex_initialize(& FILES[i]->lock);195 vfs_file_addref( FILES[i]);196 fibril_mutex_unlock(& VFS_DATA->lock);206 memset(vfs_data->files[i], 0, sizeof(vfs_file_t)); 207 fibril_mutex_initialize(&vfs_data->files[i]->lock); 208 vfs_file_addref(vfs_data, vfs_data->files[i]); 209 fibril_mutex_unlock(&vfs_data->lock); 197 210 return (int) i; 198 211 } … … 210 223 } 211 224 } 212 fibril_mutex_unlock(& VFS_DATA->lock);225 fibril_mutex_unlock(&vfs_data->lock); 213 226 214 227 return EMFILE; 228 } 229 230 /** Allocate a file descriptor. 231 * 232 * @param desc If true, look for an available file descriptor 233 * in a descending order. 234 * 235 * @return First available file descriptor or a negative error 236 * code. 237 */ 238 int vfs_fd_alloc(bool desc) 239 { 240 return _vfs_fd_alloc(VFS_DATA, desc); 241 } 242 243 static int _vfs_fd_free(vfs_client_data_t *vfs_data, int fd) 244 { 245 int rc; 246 247 if (!vfs_files_init(vfs_data)) 248 return ENOMEM; 249 250 fibril_mutex_lock(&vfs_data->lock); 251 if ((fd < 0) || (fd >= MAX_OPEN_FILES) || !vfs_data->files[fd]) { 252 fibril_mutex_unlock(&vfs_data->lock); 253 return EBADF; 254 } 255 256 rc = vfs_file_delref(vfs_data, vfs_data->files[fd]); 257 vfs_data->files[fd] = NULL; 258 fibril_mutex_unlock(&vfs_data->lock); 259 260 return rc; 215 261 } 216 262 … … 224 270 int vfs_fd_free(int fd) 225 271 { 226 int rc; 227 228 if (!vfs_files_init()) 229 return ENOMEM; 230 231 fibril_mutex_lock(&VFS_DATA->lock); 232 if ((fd < 0) || (fd >= MAX_OPEN_FILES) || (FILES[fd] == NULL)) { 233 fibril_mutex_unlock(&VFS_DATA->lock); 234 return EBADF; 235 } 236 237 rc = vfs_file_delref(FILES[fd]); 238 FILES[fd] = NULL; 239 fibril_mutex_unlock(&VFS_DATA->lock); 240 241 return rc; 272 return _vfs_fd_free(VFS_DATA, fd); 242 273 } 243 274 … … 253 284 int vfs_fd_assign(vfs_file_t *file, int fd) 254 285 { 255 if (!vfs_files_init( ))286 if (!vfs_files_init(VFS_DATA)) 256 287 return ENOMEM; 257 288 … … 263 294 264 295 FILES[fd] = file; 265 vfs_file_addref( FILES[fd]);296 vfs_file_addref(VFS_DATA, FILES[fd]); 266 297 fibril_mutex_unlock(&VFS_DATA->lock); 267 298 … … 269 300 } 270 301 271 /** Find VFS file structure for a given file descriptor. 272 * 273 * @param fd File descriptor. 274 * 275 * @return VFS file structure corresponding to fd. 276 */ 277 vfs_file_t *vfs_file_get(int fd) 278 { 279 if (!vfs_files_init()) 302 static vfs_file_t *_vfs_file_get(vfs_client_data_t *vfs_data, int fd) 303 { 304 if (!vfs_files_init(vfs_data)) 280 305 return NULL; 281 306 282 fibril_mutex_lock(& VFS_DATA->lock);307 fibril_mutex_lock(&vfs_data->lock); 283 308 if ((fd >= 0) && (fd < MAX_OPEN_FILES)) { 284 vfs_file_t *file = FILES[fd];309 vfs_file_t *file = vfs_data->files[fd]; 285 310 if (file != NULL) { 286 vfs_file_addref( file);287 fibril_mutex_unlock(& VFS_DATA->lock);311 vfs_file_addref(vfs_data, file); 312 fibril_mutex_unlock(&vfs_data->lock); 288 313 return file; 289 314 } 290 315 } 291 fibril_mutex_unlock(& VFS_DATA->lock);316 fibril_mutex_unlock(&vfs_data->lock); 292 317 293 318 return NULL; 294 319 } 295 320 321 /** Find VFS file structure for a given file descriptor. 322 * 323 * @param fd File descriptor. 324 * 325 * @return VFS file structure corresponding to fd. 326 */ 327 vfs_file_t *vfs_file_get(int fd) 328 { 329 return _vfs_file_get(VFS_DATA, fd); 330 } 331 332 static void _vfs_file_put(vfs_client_data_t *vfs_data, vfs_file_t *file) 333 { 334 fibril_mutex_lock(&vfs_data->lock); 335 vfs_file_delref(vfs_data, file); 336 fibril_mutex_unlock(&vfs_data->lock); 337 } 338 296 339 /** Stop using a file structure. 297 340 * … … 300 343 void vfs_file_put(vfs_file_t *file) 301 344 { 302 fibril_mutex_lock(&VFS_DATA->lock); 303 vfs_file_delref(file); 304 fibril_mutex_unlock(&VFS_DATA->lock); 345 _vfs_file_put(VFS_DATA, file); 346 } 347 348 void vfs_pass_handle(sysarg_t donor_hash, sysarg_t acceptor_hash, int donor_fd) 349 { 350 vfs_client_data_t *donor_data = NULL; 351 vfs_client_data_t *acceptor_data = NULL; 352 vfs_file_t *donor_file = NULL; 353 vfs_file_t *acceptor_file = NULL; 354 vfs_boxed_handle_t *bh; 355 int acceptor_fd; 356 357 acceptor_data = async_get_client_data_by_hash(acceptor_hash); 358 if (!acceptor_data) 359 return; 360 361 bh = malloc(sizeof(vfs_boxed_handle_t)); 362 assert(bh); 363 364 link_initialize(&bh->link); 365 bh->handle = -1; 366 367 donor_data = async_get_client_data_by_hash(donor_hash); 368 if (!donor_data) 369 goto out; 370 371 donor_file = _vfs_file_get(donor_data, donor_fd); 372 if (!donor_file) 373 goto out; 374 375 acceptor_fd = _vfs_fd_alloc(acceptor_data, false); 376 if (acceptor_fd < 0) 377 goto out; 378 379 bh->handle = acceptor_fd; 380 381 /* 382 * Add a new reference to the underlying VFS node. 383 */ 384 vfs_node_addref(donor_file->node); 385 (void) vfs_open_node_remote(donor_file->node); 386 387 acceptor_file = _vfs_file_get(acceptor_data, acceptor_fd); 388 assert(acceptor_file); 389 390 /* 391 * Inherit attributes from the donor. 392 */ 393 acceptor_file->node = donor_file->node; 394 acceptor_file->append = donor_file->append; 395 acceptor_file->pos = donor_file->pos; 396 397 out: 398 fibril_mutex_lock(&acceptor_data->lock); 399 list_append(&bh->link, &acceptor_data->passed_handles); 400 fibril_condvar_broadcast(&acceptor_data->cv); 401 fibril_mutex_unlock(&acceptor_data->lock); 402 403 if (donor_data) 404 async_put_client_data_by_hash(donor_hash); 405 if (acceptor_data) 406 async_put_client_data_by_hash(acceptor_hash); 407 if (donor_file) 408 _vfs_file_put(donor_data, donor_file); 409 if (acceptor_file) 410 _vfs_file_put(acceptor_data, acceptor_file); 411 412 } 413 414 int vfs_wait_handle_internal(void) 415 { 416 vfs_client_data_t *vfs_data = VFS_DATA; 417 int fd; 418 419 fibril_mutex_lock(&vfs_data->lock); 420 while (list_empty(&vfs_data->passed_handles)) 421 fibril_condvar_wait(&vfs_data->cv, &vfs_data->lock); 422 link_t *lnk = list_first(&vfs_data->passed_handles); 423 list_remove(lnk); 424 fibril_mutex_unlock(&vfs_data->lock); 425 426 vfs_boxed_handle_t *bh = list_get_instance(lnk, vfs_boxed_handle_t, link); 427 fd = bh->handle; 428 free(bh); 429 430 return fd; 305 431 } 306 432 -
uspace/srv/vfs/vfs_lookup.c
ref7052ec r42a619b 201 201 } 202 202 203 /** Perform a node open operation.204 *205 * @return EOK on success or an error code from errno.h.206 *207 */208 int vfs_open_node_internal(vfs_lookup_res_t *result)209 {210 async_exch_t *exch = vfs_exchange_grab(result->triplet.fs_handle);211 212 ipc_call_t answer;213 aid_t req = async_send_2(exch, VFS_OUT_OPEN_NODE,214 (sysarg_t) result->triplet.service_id,215 (sysarg_t) result->triplet.index, &answer);216 217 sysarg_t rc;218 async_wait_for(req, &rc);219 vfs_exchange_release(exch);220 221 if (rc == EOK) {222 result->size =223 MERGE_LOUP32(IPC_GET_ARG1(answer), IPC_GET_ARG2(answer));224 result->lnkcnt = (unsigned int) IPC_GET_ARG3(answer);225 if (IPC_GET_ARG4(answer) & L_FILE)226 result->type = VFS_NODE_FILE;227 else if (IPC_GET_ARG4(answer) & L_DIRECTORY)228 result->type = VFS_NODE_DIRECTORY;229 else230 result->type = VFS_NODE_UNKNOWN;231 }232 233 return rc;234 }235 236 203 /** 237 204 * @} -
uspace/srv/vfs/vfs_node.c
ref7052ec r42a619b 293 293 } 294 294 295 296 /** Perform a remote node open operation. 297 * 298 * @return EOK on success or an error code from errno.h. 299 * 300 */ 301 int vfs_open_node_remote(vfs_node_t *node) 302 { 303 async_exch_t *exch = vfs_exchange_grab(node->fs_handle); 304 305 ipc_call_t answer; 306 aid_t req = async_send_2(exch, VFS_OUT_OPEN_NODE, 307 (sysarg_t) node->service_id, (sysarg_t) node->index, &answer); 308 309 vfs_exchange_release(exch); 310 311 sysarg_t rc; 312 async_wait_for(req, &rc); 313 314 return rc; 315 } 316 295 317 /** 296 318 * @} -
uspace/srv/vfs/vfs_ops.c
ref7052ec r42a619b 618 618 } 619 619 620 void vfs_open_node(ipc_callid_t rid, ipc_call_t *request)621 {622 // FIXME: check for sanity of the supplied fs, dev and index623 624 /*625 * The interface is open_node(fs, dev, index, oflag).626 */627 vfs_lookup_res_t lr;628 629 lr.triplet.fs_handle = IPC_GET_ARG1(*request);630 lr.triplet.service_id = IPC_GET_ARG2(*request);631 lr.triplet.index = IPC_GET_ARG3(*request);632 int oflag = IPC_GET_ARG4(*request);633 634 fibril_rwlock_read_lock(&namespace_rwlock);635 636 int rc = vfs_open_node_internal(&lr);637 if (rc != EOK) {638 fibril_rwlock_read_unlock(&namespace_rwlock);639 async_answer_0(rid, rc);640 return;641 }642 643 vfs_node_t *node = vfs_node_get(&lr);644 fibril_rwlock_read_unlock(&namespace_rwlock);645 646 /* Truncate the file if requested and if necessary. */647 if (oflag & O_TRUNC) {648 fibril_rwlock_write_lock(&node->contents_rwlock);649 if (node->size) {650 rc = vfs_truncate_internal(node->fs_handle,651 node->service_id, node->index, 0);652 if (rc) {653 fibril_rwlock_write_unlock(&node->contents_rwlock);654 vfs_node_put(node);655 async_answer_0(rid, rc);656 return;657 }658 node->size = 0;659 }660 fibril_rwlock_write_unlock(&node->contents_rwlock);661 }662 663 /*664 * Get ourselves a file descriptor and the corresponding vfs_file_t665 * structure.666 */667 int fd = vfs_fd_alloc((oflag & O_DESC) != 0);668 if (fd < 0) {669 vfs_node_put(node);670 async_answer_0(rid, fd);671 return;672 }673 vfs_file_t *file = vfs_file_get(fd);674 file->node = node;675 if (oflag & O_APPEND)676 file->append = true;677 678 /*679 * The following increase in reference count is for the fact that the680 * file is being opened and that a file structure is pointing to it.681 * It is necessary so that the file will not disappear when682 * vfs_node_put() is called. The reference will be dropped by the683 * respective VFS_IN_CLOSE.684 */685 vfs_node_addref(node);686 vfs_node_put(node);687 vfs_file_put(file);688 689 /* Success! Return the new file descriptor to the client. */690 async_answer_1(rid, EOK, fd);691 }692 693 620 void vfs_sync(ipc_callid_t rid, ipc_call_t *request) 694 621 { … … 1349 1276 } 1350 1277 1278 void vfs_wait_handle(ipc_callid_t rid, ipc_call_t *request) 1279 { 1280 int fd = vfs_wait_handle_internal(); 1281 async_answer_1(rid, EOK, fd); 1282 } 1283 1351 1284 /** 1352 1285 * @}
Note:
See TracChangeset
for help on using the changeset viewer.