diff options
-rw-r--r-- | netfs/fuse/fuseApp.cpp | 3 | ||||
-rw-r--r-- | netfs/fuse/fuseAppBase.h | 105 | ||||
-rw-r--r-- | netfs/unittests/testCore.cpp | 3 |
3 files changed, 58 insertions, 53 deletions
diff --git a/netfs/fuse/fuseApp.cpp b/netfs/fuse/fuseApp.cpp index f9b6884..cfd9689 100644 --- a/netfs/fuse/fuseApp.cpp +++ b/netfs/fuse/fuseApp.cpp @@ -20,9 +20,6 @@ namespace AdHoc { template class CallCacheable<struct stat, std::string>; } -static_assert(NetFS::FuseApp::operations.access); -static_assert(!NetFS::FuseApp::operations.destroy); - NetFS::FuseApp::FuseApp(Ice::StringSeq && a) : iceArgs(std::move(a)) { } NetFS::FuseApp::~FuseApp() diff --git a/netfs/fuse/fuseAppBase.h b/netfs/fuse/fuseAppBase.h index e4c1c62..7d8edce 100644 --- a/netfs/fuse/fuseAppBase.h +++ b/netfs/fuse/fuseAppBase.h @@ -74,15 +74,67 @@ public: protected: static FuseAppBase * fuseApp; + + template<bool Implemented, auto bfunc> + constexpr static auto + getInternalHelper() + { + if constexpr (Implemented) { + return [](auto... a) { + SharedLock(fuseApp->_lock); + return (fuseApp->*bfunc)(a...); + }; + } + else { + return nullptr; + } + } + + template<bool Implemented, auto bfunc> + constexpr static auto + getHelper() + { + if constexpr (Implemented) { + return [](auto... a) -> decltype((fuseApp->*bfunc)(a...)) { + for (int t = 0;; ++t) { + try { + fuseApp->beforeOperation(); + SharedLock(fuseApp->_lock); + return (fuseApp->*bfunc)(a...); + } + catch (const std::exception & ex) { + if (t < 10) { + if (int rtn = fuseApp->onError(ex)) { + return rtn; + } + } + else { + fuseApp->logf( + LOG_ERR, "Retries expired with %s calling %s", ex.what(), typeid(bfunc).name()); + return -EIO; + } + } + catch (...) { + fuseApp->logf(LOG_ERR, "Unknown exception calling %s", typeid(bfunc).name()); + return -EIO; + } + } + }; + } + else { + return nullptr; + } + } }; template<typename FuseApp> class FuseAppBaseT : public FuseAppBase { +private: public: #define GetIntHelper(func) \ - getInternalHelper<decltype(&FuseAppBase::func), decltype(&FuseApp::func), &FuseAppBase::func>(&FuseAppBase::func) + getInternalHelper<!std::is_same_v<decltype(&FuseAppBase::func), decltype(&FuseApp::func)>, &FuseAppBase::func>() #define GetHelper(func) \ - getHelper<decltype(&FuseAppBase::func), decltype(&FuseApp::func), &FuseAppBase::func>(&FuseAppBase::func) - constexpr static fuse_operations operations { + getHelper<!std::is_same_v<decltype(&FuseAppBase::func), decltype(&FuseApp::func)>, &FuseAppBase::func>() + constexpr const static fuse_operations operations { GetHelper(getattr), GetHelper(readlink), GetHelper(mknod), @@ -129,53 +181,6 @@ public: #undef GetHelper #undef GetIntHelper -private: - template<typename BFunc, typename IFunc, BFunc bfunc, typename Rtn, typename... Args> - constexpr static auto - getInternalHelper(Rtn (FuseAppBase::*)(Args...)) -> Rtn (*)(Args...) - { - if constexpr (!std::is_same<BFunc, IFunc>::value) { - return [](Args... a) { - SharedLock(fuseApp->_lock); - return (fuseApp->*bfunc)(a...); - }; - } - return nullptr; - } - template<typename BFunc, typename IFunc, BFunc bfunc, typename Rtn, typename... Args> - constexpr static auto - getHelper(Rtn (FuseAppBase::*)(Args...)) -> Rtn (*)(Args...) - { - if constexpr (!std::is_same<BFunc, IFunc>::value) { - return [](Args... a) -> Rtn { - for (int t = 0;; ++t) { - try { - fuseApp->beforeOperation(); - SharedLock(fuseApp->_lock); - return (fuseApp->*bfunc)(a...); - } - catch (const std::exception & ex) { - if (t < 10) { - if (int rtn = fuseApp->onError(ex)) { - return rtn; - } - } - else { - fuseApp->logf( - LOG_ERR, "Retries expired with %s calling %s", ex.what(), typeid(bfunc).name()); - return -EIO; - } - } - catch (...) { - fuseApp->logf(LOG_ERR, "Unknown exception calling %s", typeid(bfunc).name()); - return -EIO; - } - } - }; - } - return nullptr; - } - protected: template<typename Func, Func f, typename... Args> static int diff --git a/netfs/unittests/testCore.cpp b/netfs/unittests/testCore.cpp index 717cc16..385b826 100644 --- a/netfs/unittests/testCore.cpp +++ b/netfs/unittests/testCore.cpp @@ -86,6 +86,9 @@ BOOST_FIXTURE_TEST_SUITE(NetfsCore, Core); BOOST_AUTO_TEST_CASE(fuse_operations_correct) { + BOOST_CHECK(NetFS::FuseApp::operations.access); + BOOST_CHECK(!NetFS::FuseApp::operations.destroy); + // open should be defined BOOST_REQUIRE(fuse->open); // bmap should not be defined (Not supported) |