| 2864 | size_t ckeys() { return ckeysLoaded; } |
| 2865 | |
| 2866 | size_t endWork() { |
| 2867 | if (!fLaunched) { |
| 2868 | return ckeysLoaded; |
| 2869 | } |
| 2870 | if (!vecbatch.empty()) { |
| 2871 | queueJobs.enqueue_bulk(vecbatch.data(), vecbatch.size()); |
| 2872 | vecbatch.clear(); |
| 2873 | } |
| 2874 | std::atomic_thread_fence(std::memory_order_seq_cst); // The queue must have transferred to the consumer before we call fExit |
| 2875 | serverAssert(fLaunched); |
| 2876 | fExit = true; |
| 2877 | if (g_pserver->m_pstorageFactory) { |
| 2878 | // If we have a storage provider it can take some time to complete and we want to process events in the meantime |
| 2879 | while (!workerThreadDone) { |
| 2880 | usleep(10); |
| 2881 | pauseExecution(); |
| 2882 | ProcessWhileBlocked(); |
| 2883 | resumeExecution(); |
| 2884 | } |
| 2885 | } |
| 2886 | m_thread.join(); |
| 2887 | while (cstorageWritesInFlight.load(std::memory_order_seq_cst)) { |
| 2888 | usleep(10); |
| 2889 | ProcessWhileBlocked(); |
| 2890 | } |
| 2891 | fLaunched = false; |
| 2892 | fExit = false; |
| 2893 | serverAssert(queueJobs.size_approx() == 0); |
| 2894 | return ckeysLoaded; |
| 2895 | } |
| 2896 | |
| 2897 | void processJob(rdbInsertJob &job) { |
| 2898 | redisObjectStack keyobj; |
no test coverage detected