1.1 --- a/libfsclient/lib/src/file.cc Sat May 15 23:38:39 2021 +0200
1.2 +++ b/libfsclient/lib/src/file.cc Tue May 18 00:55:20 2021 +0200
1.3 @@ -21,11 +21,19 @@
1.4
1.5 #include <ipc/cap_alloc.h>
1.6 #include <ipc/mem_ipc.h>
1.7 +#include <ipc/irq.h>
1.8 +
1.9 +#include <l4/sys/irq.h>
1.10 +
1.11 +#include <pthread.h>
1.12 +#include <pthread-l4.h>
1.13
1.14 #include <string.h>
1.15
1.16 #include "dataspace_client.h"
1.17 #include "file_client.h"
1.18 +#include "flush_client.h"
1.19 +#include "notification_client.h"
1.20 #include "opener_client.h"
1.21 #include "opener_context_client.h"
1.22 #include "pipe_client.h"
1.23 @@ -65,12 +73,14 @@
1.24 {
1.25 file->memory = NULL;
1.26 file->ref = L4_INVALID_CAP;
1.27 + file->irq = L4_INVALID_CAP;
1.28 file->start_pos = 0;
1.29 file->end_pos = 0;
1.30 file->data_end = 0;
1.31 file->data_current = 0;
1.32 file->can_mmap = 1;
1.33 file->has_size = 1;
1.34 + file->can_block = 0;
1.35 }
1.36
1.37
1.38 @@ -82,6 +92,9 @@
1.39 if (l4_is_valid_cap(file->ref))
1.40 ipc_cap_free_um(file->ref);
1.41
1.42 + if (l4_is_valid_cap(file->irq))
1.43 + ipc_cap_free_um(file->irq);
1.44 +
1.45 if (file->memory != NULL)
1.46 ipc_detach_dataspace(file->memory);
1.47
1.48 @@ -163,7 +176,7 @@
1.49
1.50 long file_flush(file_t *file)
1.51 {
1.52 - client_File _file(file->ref);
1.53 + client_Flush _file(file->ref);
1.54 long err = _file.flush(file->data_current, &file->size);
1.55
1.56 if (err)
1.57 @@ -361,6 +374,41 @@
1.58
1.59
1.60
1.61 +/* Subscribe to notification events on a file. */
1.62 +
1.63 +long file_notify_subscribe(file_t *file, flags_t flags)
1.64 +{
1.65 + client_Notification notify(file->ref);
1.66 +
1.67 + return notify.subscribe(flags, &file->irq);
1.68 +}
1.69 +
1.70 +/* Unsubscribe from notification events on a file. */
1.71 +
1.72 +long file_notify_unsubscribe(file_t *file)
1.73 +{
1.74 + client_Notification notify(file->ref);
1.75 +
1.76 + return notify.unsubscribe();
1.77 +}
1.78 +
1.79 +/* Wait for notification events on a file. */
1.80 +
1.81 +long file_notify_wait(file_t *file)
1.82 +{
1.83 + long err = ipc_bind_irq(file->irq, (l4_umword_t) &file->irq, pthread_l4_cap(pthread_self()));
1.84 +
1.85 + if (err)
1.86 + return err;
1.87 +
1.88 + l4_msgtag_t tag = l4_irq_receive(file->irq, L4_IPC_NEVER);
1.89 +
1.90 + l4_irq_detach(file->irq);
1.91 + return l4_error(tag);
1.92 +}
1.93 +
1.94 +
1.95 +
1.96 /* Open two pipe endpoints using the given pipe server. */
1.97
1.98 long pipe_open(offset_t size, file_t *reader, file_t *writer, l4_cap_idx_t server)
1.99 @@ -401,19 +449,20 @@
1.100 {
1.101 client_Pipe _pipe(pipe->ref);
1.102 long err = _pipe.current_region(&pipe->data_end, &pipe->size);
1.103 - char *memory = pipe->memory;
1.104
1.105 if (err)
1.106 return err;
1.107
1.108 pipe->end_pos = pipe->size;
1.109
1.110 - err = ipc_attach_dataspace(pipe->ref, file_span(pipe), (void **) &pipe->memory);
1.111 - if (err)
1.112 - return err;
1.113 + /* Attach memory if necessary. */
1.114
1.115 - if (memory != NULL)
1.116 - ipc_detach_dataspace(memory);
1.117 + if (pipe->memory == NULL)
1.118 + {
1.119 + err = ipc_attach_dataspace(pipe->ref, file_span(pipe), (void **) &pipe->memory);
1.120 + if (err)
1.121 + return err;
1.122 + }
1.123
1.124 return L4_EOK;
1.125 }