/
usr
/
src
/
file_protector-1.1-1506
/
transport
/
File Upload :
llllll
Current File: //usr/src/file_protector-1.1-1506/transport/thread_safe_path.h
/** @file thread_safe_path.h @brief Thread safe accessor to the 'struct path' @details Copyright (c) 2022 Acronis International GmbH @author Denis Kopyrin (denis.kopyrin@acronis.com) @since $Id: $ */ #pragma once #include <linux/path.h> #include <linux/spinlock.h> #include <linux/types.h> // bool, [u]int(8|16|32|64)_t, pid_t, size_t // This structure is made to avoid the limitations of 'struct path' // It is only allowed to call 'path_put' and 'path_get' in the same // thread. // With this limitation it is not allowed to just use ref counting // and there must be an explicit 'path_put' from the same thread // that had 'struct path' created. typedef struct { spinlock_t spinlock; struct path path; } thread_safe_path_t; static inline void thread_safe_path_init(thread_safe_path_t *sp) { spin_lock_init(&sp->spinlock); sp->path = (struct path){}; } // No 'deinit', caller must explicitly invoke 'thread_safe_path_clear' as 'thread_safe_path_store_*' // Performs 'move' semantic and write directly to the 'path' assuming it is empty currently static inline void thread_safe_path_store_move_directly(thread_safe_path_t *sp, struct path *newpath) { spin_lock(&sp->spinlock); sp->path = *newpath; *newpath = (struct path){}; spin_unlock(&sp->spinlock); } // Clears the path stored, must be called from the same thread as 'thread_safe_path_store_*' static inline void thread_safe_path_clear(thread_safe_path_t *sp) { struct path cleared_path; spin_lock(&sp->spinlock); cleared_path = sp->path; sp->path = (struct path){}; spin_unlock(&sp->spinlock); // 'path_put' might sleep, do NOT call inside the 'spin_lock' path_put(&cleared_path); } // Loads the path from 'thread_safe_path'. Must be 'path_put' after use in the same thread. static inline void thread_safe_path_load(thread_safe_path_t *sp, struct path *to) { spin_lock(&sp->spinlock); *to = sp->path; // 'path_get' can be safely called under the 'spin_lock'. // It is the only place where 'path_get' can be reliable get path_get(to); spin_unlock(&sp->spinlock); }
Copyright ©2k19 -
Hexid
|
Tex7ure