# HG changeset patch # User Paul Boddie # Date 1676655583 -3600 # Node ID 4cc570dec22f7403f9a0412b5231d50ad563a581 # Parent 666045bae945ff21ef68fcc8f627a7bd27730639 Introduced generic notifier types to the notification mechanism. diff -r 666045bae945 -r 4cc570dec22f libfsclient/include/fsclient/file.h --- a/libfsclient/include/fsclient/file.h Thu Feb 16 23:36:52 2023 +0100 +++ b/libfsclient/include/fsclient/file.h Fri Feb 17 18:39:43 2023 +0100 @@ -41,7 +41,7 @@ EXTERN_C_BEGIN -/* File access abstraction. */ +/* File access abstraction compatible with notifiable_base_t. */ typedef struct { @@ -71,9 +71,9 @@ notify_flags_t can_block; - /* Saved notifications. */ + /* Notification structure. */ - notify_flags_t notifications; + notifiable_t notifiable; /* Flags indicated when opening the file. */ @@ -148,6 +148,9 @@ /* Notification functions. */ +notifiable_t *file_notifiable(file_t *file); +notify_flags_t file_notifications(file_t *file); + void file_notify_close(file_notifier_t *notifier); file_notifier_t *file_notify_local(void); file_notifier_t *file_notify_task(void); diff -r 666045bae945 -r 4cc570dec22f libfsclient/include/fsclient/notifier.h --- a/libfsclient/include/fsclient/notifier.h Thu Feb 16 23:36:52 2023 +0100 +++ b/libfsclient/include/fsclient/notifier.h Fri Feb 17 18:39:43 2023 +0100 @@ -1,7 +1,7 @@ /* - * File event notification support. + * Generic object event notification support. * - * Copyright (C) 2021 Paul Boddie + * Copyright (C) 2021, 2022, 2023 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -31,9 +31,9 @@ -/* File-specific notification details. */ +/* Object-specific notification details. */ -class FileNotificationState +class ObjectNotificationState { public: /* Synchronisation primitives for state access and notification. */ @@ -41,11 +41,11 @@ std::mutex lock; std::condition_variable condition; - /* Pending notifications for monitored files. */ + /* Pending notifications for monitored objects. */ notify_flags_t pending = 0; - /* Endpoints associated with monitored files. */ + /* Endpoints associated with monitored objects. */ l4_cap_idx_t endpoint = L4_INVALID_CAP; @@ -56,53 +56,53 @@ /* Collection types. */ -typedef std::map FileNotificationStates; -typedef std::map FileStateLocks; +typedef std::map ObjectNotificationStates; +typedef std::map ObjectStateLocks; -/* An object for monitoring file event notifications. */ +/* An object for monitoring object event notifications. */ -class FileNotifier +class ObjectNotifier { protected: /* General state access locking. */ std::mutex _state_lock; - /* File-specific state locking. */ + /* Object-specific state locking. */ - FileStateLocks _file_locks; + ObjectStateLocks _object_locks; /* Notification state. */ - FileNotificationStates _state; + ObjectNotificationStates _state; /* Notifier thread details. */ l4_cap_idx_t _thread = L4_INVALID_CAP; bool _started = false; - /* Convenience method to access file state. */ + /* Convenience method to access object state. */ - virtual FileNotificationState &file_state(file_t *file, bool create); + virtual ObjectNotificationState &object_state(notifiable_t *object, bool create); /* Helper methods. */ - virtual void _notify(file_t *file, notify_flags_t flags) = 0; + virtual void _notify(notifiable_t *object, notify_flags_t flags) = 0; - virtual bool _transfer(FileNotificationState &state, file_t *file); + virtual bool _transfer(ObjectNotificationState &state, notifiable_t *object); public: - virtual ~FileNotifier(); + virtual ~ObjectNotifier(); /* Local operations. */ virtual long start(); - virtual long subscribe(file_t *file, notify_flags_t flags); + virtual long subscribe(notifiable_t *object, notify_flags_t flags); - virtual long unsubscribe(file_t *file); + virtual long unsubscribe(notifiable_t *object); /* Event handling support. */ @@ -111,9 +111,9 @@ -/* An object monitoring notifications for a collection of different files. */ +/* An object monitoring notifications for a collection of different objects. */ -class GeneralFileNotifier : public FileNotifier +class GeneralObjectNotifier : public ObjectNotifier { protected: /* Locking to protect pending notification members and to coordinate access @@ -125,43 +125,43 @@ std::condition_variable _general_condition; - /* Files affected by notifications. */ + /* Objects affected by notifications. */ - std::list _affected; + std::list _affected; /* Helper methods. */ - virtual void _notify(file_t *file, notify_flags_t flags); + virtual void _notify(notifiable_t *object, notify_flags_t flags); - virtual bool _retrieve(file_t **file); + virtual bool _retrieve(notifiable_t **object); - virtual bool _retrieve_for_file(file_t *file); + virtual bool _retrieve_for_object(notifiable_t *object); public: - virtual long wait(file_t **file); + virtual long wait(notifiable_t **object); }; -/* An object monitoring notifications for specific files. */ +/* An object monitoring notifications for specific objects. */ -class SpecificFileNotifier : public FileNotifier +class SpecificObjectNotifier : public ObjectNotifier { protected: /* Helper methods. */ - virtual void _notify(file_t *file, notify_flags_t flags); + virtual void _notify(notifiable_t *object, notify_flags_t flags); public: - virtual long wait_file(file_t *file); + virtual long wait_object(notifiable_t *object); }; /* Helper functions. */ -SpecificFileNotifier *notifier_get_task_notifier(); +SpecificObjectNotifier *notifier_get_task_notifier(); -GeneralFileNotifier *notifier_get_local_notifier(); +GeneralObjectNotifier *notifier_get_local_notifier(); // vim: tabstop=4 expandtab shiftwidth=4 diff -r 666045bae945 -r 4cc570dec22f libfsclient/lib/src/client.cc --- a/libfsclient/lib/src/client.cc Thu Feb 16 23:36:52 2023 +0100 +++ b/libfsclient/lib/src/client.cc Fri Feb 17 18:39:43 2023 +0100 @@ -150,7 +150,7 @@ static int _operation_blocking(file_t *file, int reading) { - return (file->can_block && !(file->notifications & NOTIFY_PEER_CLOSED) && ( + return (file->can_block && !(file->notifiable.notifications & NOTIFY_PEER_CLOSED) && ( (reading && !file_data_available(file)) || (!reading && !file_data_space(file)))); } diff -r 666045bae945 -r 4cc570dec22f libfsclient/lib/src/file.cc --- a/libfsclient/lib/src/file.cc Thu Feb 16 23:36:52 2023 +0100 +++ b/libfsclient/lib/src/file.cc Fri Feb 17 18:39:43 2023 +0100 @@ -89,9 +89,13 @@ file->data_current = 0; file->object_flags = 0; file->can_block = 0; - file->notifications = 0; file->flags = 0; file->error = 0; + + /* Initialise the notifiable section of the structure. */ + + file->notifiable.notifications = 0; + file->notifiable.base = (notifiable_base_t *) file; } @@ -107,7 +111,7 @@ /* Only unsubscribe after actually closing the file and sending any notifications. */ - notifier_get_task_notifier()->unsubscribe(file); + notifier_get_task_notifier()->unsubscribe(file_notifiable(file)); } if (file->memory != NULL) @@ -607,10 +611,22 @@ struct file_notifier { - FileNotifier *obj; + ObjectNotifier *obj; }; +/* Conversion to the generic notification types. */ +notifiable_t *file_notifiable(file_t *file) +{ + return &file->notifiable; +} + +/* Return the notification flags for a file. */ + +notify_flags_t file_notifications(file_t *file) +{ + return file->notifiable.notifications; +} /* Close a notifier object. */ @@ -644,26 +660,26 @@ long file_notify_subscribe(file_t *file, notify_flags_t flags, file_notifier_t *notifier) { - return notifier->obj->subscribe(file, flags); + return notifier->obj->subscribe(file_notifiable(file), flags); } /* Unsubscribe from notification events on a file. */ long file_notify_unsubscribe(file_t *file, file_notifier_t *notifier) { - return notifier->obj->unsubscribe(file); + return notifier->obj->unsubscribe(file_notifiable(file)); } /* Wait for a notification event on a file. */ long file_notify_wait_file(file_t *file, file_notifier_t *notifier) { - SpecificFileNotifier *specific_notifier = dynamic_cast(notifier->obj); - long err = specific_notifier->wait_file(file); + SpecificObjectNotifier *specific_notifier = dynamic_cast(notifier->obj); + long err = specific_notifier->wait_object(file_notifiable(file)); /* Unsubscribe if a closure notification has been received. */ - if (!err && (file->notifications & NOTIFY_PEER_CLOSED)) + if (!err && (file->notifiable.notifications & NOTIFY_PEER_CLOSED)) file_notify_unsubscribe(file, notifier); return err; @@ -673,12 +689,15 @@ long file_notify_wait_files(file_t **file, file_notifier_t *notifier) { - GeneralFileNotifier *general_notifier = dynamic_cast(notifier->obj); - long err = general_notifier->wait(file); + GeneralObjectNotifier *general_notifier = dynamic_cast(notifier->obj); + notifiable_t *notifiable; + long err = general_notifier->wait(¬ifiable); + + *file = (file_t *) notifiable->base; /* Unsubscribe if a closure notification has been received. */ - if (!err && ((*file)->notifications & NOTIFY_PEER_CLOSED)) + if (!err && ((*file)->notifiable.notifications & NOTIFY_PEER_CLOSED)) file_notify_unsubscribe(*file, notifier); return err; diff -r 666045bae945 -r 4cc570dec22f libfsclient/lib/src/notifier.cc --- a/libfsclient/lib/src/notifier.cc Thu Feb 16 23:36:52 2023 +0100 +++ b/libfsclient/lib/src/notifier.cc Fri Feb 17 18:39:43 2023 +0100 @@ -1,7 +1,7 @@ /* - * File event notification support. + * Generic object event notification support. * - * Copyright (C) 2021, 2022 Paul Boddie + * Copyright (C) 2021, 2022, 2023 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -35,7 +35,7 @@ /* Null notification state. */ -static FileNotificationState _null_state; +static ObjectNotificationState _null_state; @@ -45,13 +45,13 @@ /* Per-task storage for specific waiting operations. */ -static SpecificFileNotifier *_notifier = NULL; +static SpecificObjectNotifier *_notifier = NULL; -/* Return the per-task notifier for file-specific waiting operations. */ +/* Return the per-task notifier for object-specific waiting operations. */ -SpecificFileNotifier *notifier_get_task_notifier() +SpecificObjectNotifier *notifier_get_task_notifier() { std::lock_guard guard(_lock); @@ -59,18 +59,18 @@ if (_notifier == NULL) { - _notifier = new SpecificFileNotifier; + _notifier = new SpecificObjectNotifier; _notifier->start(); } return _notifier; } -/* Return a local notifier for general file waiting operations. */ +/* Return a local notifier for general object waiting operations. */ -GeneralFileNotifier *notifier_get_local_notifier() +GeneralObjectNotifier *notifier_get_local_notifier() { - GeneralFileNotifier *notifier = new GeneralFileNotifier; + GeneralObjectNotifier *notifier = new GeneralObjectNotifier; notifier->start(); return notifier; @@ -82,7 +82,7 @@ static void *notifier_mainloop(void *data) { - FileNotifier *notifier = reinterpret_cast(data); + ObjectNotifier *notifier = reinterpret_cast(data); notifier->mainloop(); return 0; @@ -92,13 +92,13 @@ /* Virtual destructor required for base class instance reference deletion. */ -FileNotifier::~FileNotifier() +ObjectNotifier::~ObjectNotifier() { } /* Listen for notifications. */ -void FileNotifier::mainloop() +void ObjectNotifier::mainloop() { ipc_message_t msg; l4_umword_t label; @@ -116,9 +116,9 @@ if (l4_ipc_error(msg.tag, l4_utcb())) continue; - /* Interpret gate labels as file objects. */ + /* Interpret gate labels as notifiable objects. */ - file_t *file = (file_t *) label; + notifiable_t *object = (notifiable_t *) label; /* Obtain message details. */ @@ -133,7 +133,7 @@ /* Register the notification. */ - _notify(file, flags); + _notify(object, flags); } ipc_message_free(&msg); @@ -141,7 +141,7 @@ /* Start listening for notifications. */ -long FileNotifier::start() +long ObjectNotifier::start() { if (_started) return L4_EOK; @@ -165,17 +165,17 @@ -/* Return a notification state object for the given file or a null object if no - record existed for the file. */ +/* Return notification state for the given object or null state if no record + existed for the object. */ -FileNotificationState &FileNotifier::file_state(file_t *file, bool create) +ObjectNotificationState &ObjectNotifier::object_state(notifiable_t *object, bool create) { - FileNotificationStates::iterator it = _state.find(file); + ObjectNotificationStates::iterator it = _state.find(object); if (it == _state.end()) { if (create) - return _state[file]; + return _state[object]; else return _null_state; } @@ -183,22 +183,22 @@ return it->second; } -/* Subscribe to notification events on a file. */ +/* Subscribe to notification events on an object. */ -long FileNotifier::subscribe(file_t *file, notify_flags_t flags) +long ObjectNotifier::subscribe(notifiable_t *object, notify_flags_t flags) { /* Acquire the lock for state lookup. */ std::unique_lock state_guard(_state_lock); - FileNotificationState &state = file_state(file, true); + ObjectNotificationState &state = object_state(object, true); long err; /* Create a notification endpoint, if necessary. */ if (state.is_null()) { - err = ipc_server_new_for_thread(&state.endpoint, file, _thread); + err = ipc_server_new_for_thread(&state.endpoint, object, _thread); if (err) return err; @@ -206,59 +206,59 @@ /* Subscribe, sending the notification endpoint. */ - client_Notification notify(file->ref); + client_Notification notify(object->base->ref); err = notify.subscribe(state.endpoint, flags); if (err) { ipc_cap_free_um(state.endpoint); - _state.erase(file); + _state.erase(object); return err; } return L4_EOK; } -/* Unsubscribe from notification events on a file. */ +/* Unsubscribe from notification events on an object. */ -long FileNotifier::unsubscribe(file_t *file) +long ObjectNotifier::unsubscribe(notifiable_t *object) { /* Acquire the lock for state lookup. */ std::unique_lock state_guard(_state_lock); - FileNotificationState &state = file_state(file, false); + ObjectNotificationState &state = object_state(object, false); if (state.is_null()) return -L4_EINVAL; /* Unsubscribe via the notification interface. */ - client_Notification notify(file->ref); + client_Notification notify(object->base->ref); notify.unsubscribe(); ipc_cap_free_um(state.endpoint); - _state.erase(file); + _state.erase(object); - /* Remove the lock for updating file state. */ + /* Remove the lock for updating object state. */ - _file_locks.erase(file); + _object_locks.erase(object); return L4_EOK; } -/* Handle a notification event for a file. Ideally, this would be invoked by the - generic server dispatch mechanism, with the gate label being interpreted and - provided as the first parameter. */ +/* Handle a notification event for an object. Ideally, this would be invoked by + the generic server dispatch mechanism, with the gate label being interpreted + and provided as the first parameter. */ -void GeneralFileNotifier::_notify(file_t *file, notify_flags_t flags) +void GeneralObjectNotifier::_notify(notifiable_t *object, notify_flags_t flags) { - /* Enter critical section for the notifier (affecting all files). */ + /* Enter critical section for the notifier (affecting all objects). */ std::unique_lock general_guard(_general_lock); @@ -266,14 +266,14 @@ std::unique_lock state_guard(_state_lock); - FileNotificationState &state = file_state(file, false); + ObjectNotificationState &state = object_state(object, false); if (state.is_null()) return; - /* Acquire the lock for the file state itself. */ + /* Acquire the lock for the object state itself. */ - std::unique_lock file_guard(state.lock); + std::unique_lock object_guard(state.lock); /* Record flags and return previous flags. */ @@ -281,30 +281,30 @@ state.pending |= flags; - /* Add a file queue entry for any files without previous notifications. */ + /* Add an object queue entry for any objects without previous notifications. */ if (!recorded) - _affected.push_back(file); + _affected.push_back(object); /* Notify any waiting caller. */ _general_condition.notify_one(); } -void SpecificFileNotifier::_notify(file_t *file, notify_flags_t flags) +void SpecificObjectNotifier::_notify(notifiable_t *object, notify_flags_t flags) { /* Acquire the lock for state lookup. */ std::unique_lock state_guard(_state_lock); - FileNotificationState &state = file_state(file, false); + ObjectNotificationState &state = object_state(object, false); if (state.is_null()) return; - /* Acquire the lock for the file state itself. */ + /* Acquire the lock for the object state itself. */ - std::unique_lock file_guard(state.lock); + std::unique_lock object_guard(state.lock); state.pending |= flags; @@ -315,16 +315,16 @@ -/* Transfer pending notifications to the given file. This must be called with a - lock acquired on the file notification state. */ +/* Transfer pending notifications to the given object. This must be called with + a lock acquired on the object notification state. */ -bool FileNotifier::_transfer(FileNotificationState &state, file_t *file) +bool ObjectNotifier::_transfer(ObjectNotificationState &state, notifiable_t *object) { notify_flags_t recorded = state.pending; if (recorded) { - file->notifications = recorded; + object->notifications = recorded; state.pending = 0; return true; } @@ -334,41 +334,41 @@ -/* Obtain file state and transfer notifications. */ +/* Obtain object state and transfer notifications. */ -bool GeneralFileNotifier::_retrieve_for_file(file_t *file) +bool GeneralObjectNotifier::_retrieve_for_object(notifiable_t *object) { /* Acquire the lock for state lookup. */ std::unique_lock state_guard(_state_lock); - FileNotificationState &state = file_state(file, false); + ObjectNotificationState &state = object_state(object, false); if (state.is_null()) return false; - /* Acquire the lock for the file state itself, then release the state lock. */ + /* Acquire the lock for the object state itself, then release the state lock. */ - std::unique_lock file_guard(state.lock); + std::unique_lock object_guard(state.lock); state_guard.unlock(); /* Call generic method to transfer notifications, if possible. */ - return _transfer(state, file); + return _transfer(state, object); } -/* Obtain queued files until one is found that still has events recorded for it. - This must be called with the notifier's general lock acquired. */ +/* Obtain queued objects until one is found that still has events recorded for + it. This must be called with the notifier's general lock acquired. */ -bool GeneralFileNotifier::_retrieve(file_t **file) +bool GeneralObjectNotifier::_retrieve(notifiable_t **object) { while (!_affected.empty()) { - *file = _affected.front(); + *object = _affected.front(); _affected.pop_front(); - if (_retrieve_for_file(*file)) + if (_retrieve_for_object(*object)) return true; } @@ -377,17 +377,17 @@ -/* Wait for notification events on files. */ +/* Wait for notification events on objects. */ -long GeneralFileNotifier::wait(file_t **file) +long GeneralObjectNotifier::wait(notifiable_t **object) { std::unique_lock general_guard(_general_lock); while (1) { - /* With pending notifications, update the first file and exit. */ + /* With pending notifications, update the first object and exit. */ - if (_retrieve(file)) + if (_retrieve(object)) break; /* Otherwise, wait for notifications. */ @@ -398,35 +398,35 @@ return L4_EOK; } -/* Wait for notifications from a single file. */ +/* Wait for notifications from a single object. */ -long SpecificFileNotifier::wait_file(file_t *file) +long SpecificObjectNotifier::wait_object(notifiable_t *object) { - /* Acquire the lock for reading file state. */ + /* Acquire the lock for reading object state. */ std::unique_lock state_guard(_state_lock); - FileNotificationState &state = file_state(file, false); + ObjectNotificationState &state = object_state(object, false); if (state.is_null()) return -L4_EINVAL; - /* Acquire the lock for the file state itself, then release the state lock. */ + /* Acquire the lock for the object state itself, then release the state lock. */ - std::unique_lock file_guard(state.lock); + std::unique_lock object_guard(state.lock); state_guard.unlock(); while (1) { - /* With pending notifications, update the file and exit. */ + /* With pending notifications, update the object and exit. */ - if (_transfer(state, file)) + if (_transfer(state, object)) break; /* Otherwise, wait for notifications. */ - state.condition.wait(file_guard); + state.condition.wait(object_guard); } return L4_EOK; diff -r 666045bae945 -r 4cc570dec22f libsystypes/include/systypes/base.h --- a/libsystypes/include/systypes/base.h Thu Feb 16 23:36:52 2023 +0100 +++ b/libsystypes/include/systypes/base.h Fri Feb 17 18:39:43 2023 +0100 @@ -1,7 +1,7 @@ /* * Base types used by various other types. * - * Copyright (C) 2019, 2021, 2022 Paul Boddie + * Copyright (C) 2019, 2021, 2022, 2023 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -49,12 +49,28 @@ enum notify_flags { - NOTIFY_CONTENT_AVAILABLE = 1, /* reading files and pipes */ - NOTIFY_SPACE_AVAILABLE = 2, /* writing pipes */ - NOTIFY_PEER_CLOSED = 4, /* closing files and pipes */ - NOTIFY_FILE_OPENED = 8, /* opening files in directories */ + NOTIFY_CONTENT_AVAILABLE = 0x001, /* reading files and pipes */ + NOTIFY_SPACE_AVAILABLE = 0x002, /* writing pipes */ + NOTIFY_PEER_CLOSED = 0x004, /* closing files and pipes */ + NOTIFY_FILE_OPENED = 0x008, /* opening files in directories */ + NOTIFY_TASK_SIGNAL = 0x100, /* signal from task */ }; +/* Notifiable object types. */ + +typedef struct +{ + l4_cap_idx_t ref; + +} notifiable_base_t; + +typedef struct +{ + notifiable_base_t *base; /* access to the specific object */ + notify_flags_t notifications; + +} notifiable_t; + /* Filesystem object properties. */ typedef unsigned long object_flags_t; diff -r 666045bae945 -r 4cc570dec22f libsystypes/include/systypes/format.h --- a/libsystypes/include/systypes/format.h Thu Feb 16 23:36:52 2023 +0100 +++ b/libsystypes/include/systypes/format.h Fri Feb 17 18:39:43 2023 +0100 @@ -1,7 +1,7 @@ /* * Format specifiers for output. * - * Copyright (C) 2022 Paul Boddie + * Copyright (C) 2022, 2023 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -40,6 +40,7 @@ /* See: systypes/base.h */ #define pFMToffset "ll" +#define pFMTnotify_flags "ll" /* Alternative for size_t or ssize_t (%z). */ diff -r 666045bae945 -r 4cc570dec22f tests/dstest_file_client.cc --- a/tests/dstest_file_client.cc Thu Feb 16 23:36:52 2023 +0100 +++ b/tests/dstest_file_client.cc Fri Feb 17 18:39:43 2023 +0100 @@ -1,7 +1,7 @@ /* * Test file operations. * - * Copyright (C) 2020, 2021, 2022 Paul Boddie + * Copyright (C) 2020, 2021, 2022, 2023 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -97,8 +97,8 @@ } printf("File %s notified with conditions:%s%s\n", creator ? "creator" : "follower", - file->notifications & NOTIFY_PEER_CLOSED ? " closed" : "", - file->notifications & NOTIFY_CONTENT_AVAILABLE ? " content" : ""); + file_notifications(file) & NOTIFY_PEER_CLOSED ? " closed" : "", + file_notifications(file) & NOTIFY_CONTENT_AVAILABLE ? " content" : ""); /* Attempt to read. */ @@ -120,7 +120,7 @@ /* Without any more content, a peer closed event should terminate reading from the file. */ - if (file->notifications & NOTIFY_PEER_CLOSED) + if (file_notifications(file) & NOTIFY_PEER_CLOSED) break; /* Otherwise, write some data to the file for the other party. */ diff -r 666045bae945 -r 4cc570dec22f tests/dstest_file_monitor.cc --- a/tests/dstest_file_monitor.cc Thu Feb 16 23:36:52 2023 +0100 +++ b/tests/dstest_file_monitor.cc Fri Feb 17 18:39:43 2023 +0100 @@ -1,7 +1,7 @@ /* * Test directory monitoring operations. * - * Copyright (C) 2020, 2021, 2022 Paul Boddie + * Copyright (C) 2020, 2021, 2022, 2023 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -87,7 +87,7 @@ return; } - printf("Notified with conditions:%s\n", directory->notifications & NOTIFY_FILE_OPENED ? " file opened" : ""); + printf("Notified with conditions:%s\n", file_notifications(directory) & NOTIFY_FILE_OPENED ? " file opened" : ""); } printf("Notified for all expected files: %s\n", expected ? "False" : "True"); diff -r 666045bae945 -r 4cc570dec22f tests/dstest_pipe_client.cc --- a/tests/dstest_pipe_client.cc Thu Feb 16 23:36:52 2023 +0100 +++ b/tests/dstest_pipe_client.cc Fri Feb 17 18:39:43 2023 +0100 @@ -1,7 +1,7 @@ /* * Test pipe operations. * - * Copyright (C) 2020, 2021, 2022 Paul Boddie + * Copyright (C) 2020, 2021, 2022, 2023 Paul Boddie * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -124,8 +124,8 @@ int p = reader == reader1 ? 0 : 1; - printf("Pipe #%d notified with conditions:%s%s\n", p + 1, reader->notifications & NOTIFY_PEER_CLOSED ? " closed" : "", - reader->notifications & NOTIFY_CONTENT_AVAILABLE ? " content" : ""); + printf("Pipe #%d notified with conditions:%s%s\n", p + 1, file_notifications(reader) & NOTIFY_PEER_CLOSED ? " closed" : "", + file_notifications(reader) & NOTIFY_CONTENT_AVAILABLE ? " content" : ""); nread = client_read(reader, buffer, TO_TRANSFER); @@ -140,7 +140,7 @@ /* Without any more content, a peer closed event should terminate reading from the pipe. */ - if (reader->notifications & NOTIFY_PEER_CLOSED) + if (file_notifications(reader) & NOTIFY_PEER_CLOSED) { active--; if (!active)