// GorevSistemi — async analiz altyapisinin dayandigi semantikleri KILITLER. // Ozellikle: iptalEt BITMIS isin bitince'sini ENGELLEMEZ (yalniz bayrak atar) — // AnalizSistemi::asyncKuyrukla'daki nesil sayaci tam bu yuzden var. Bu testler // kirilirsa nesil-guard varsayimi da gozden gecirilmeli. #include #include #include #include "fiko/cekirdek/gorev.hpp" #include "fiko/cekirdek/olay.hpp" #include "fiko_test.hpp" using namespace fiko; namespace { // pompala dongusu: is bitene (kayitlar bosalana) kadar, tavanli bekleme. void pompalaBekle(GorevSistemi& g, OlayGunlugu& o, int maksMs = 5000) { const auto t0 = std::chrono::steady_clock::now(); while (!g.bosMu()) { g.pompala(o); if (std::chrono::duration(std::chrono::steady_clock::now() - t0) .count() > maksMs) break; std::this_thread::sleep_for(std::chrono::milliseconds(1)); } } } // namespace // ---- Temel: is worker'da kosar, bitince main pompala'da BIR kez ------------ FIKO_TEST(gorev_bitince_bir_kez) { GorevSistemi g(1); OlayGunlugu o; std::atomic isKosti{0}; int bitinceKosti = 0; g.kuyrukla("t", [&](GorevBaglam&) { ++isKosti; }, [&] { ++bitinceKosti; }); pompalaBekle(g, o); FIKO_KONTROL(isKosti.load() == 1); FIKO_KONTROL(bitinceKosti == 1); FIKO_KONTROL(g.bosMu()); // biten kayit temizlendi } // ---- YUK TASIYAN VARSAYIM: bitmis ise iptalEt → bitince YINE kosar ---------- // (iptalEt yalniz bayrak atar; durum zaten Bitti ise pompala bitince'yi cagirir. // AnalizSistemi nesil sayaci bu bosluk icin var — semantik degisirse bu test // kirilir ve guard yeniden degerlendirilir.) FIKO_TEST(gorev_iptal_bitmis_isi_engellemez) { GorevSistemi g(1); OlayGunlugu o; std::atomic isBitti{false}; int bitinceKosti = 0; const u64 k = g.kuyrukla("t", [&](GorevBaglam&) { isBitti = true; }, [&] { ++bitinceKosti; }); // Worker'in isi BITIRMESINI bekle (pompala YOK → bitince henuz kosmadi). const auto t0 = std::chrono::steady_clock::now(); while (!isBitti.load() && std::chrono::duration(std::chrono::steady_clock::now() - t0) .count() < 5000) std::this_thread::sleep_for(std::chrono::milliseconds(1)); FIKO_KONTROL(isBitti.load()); g.iptalEt(k); // is coktan bitti — iptal artik sonucu degistirmemeli pompalaBekle(g, o); FIKO_KONTROL(bitinceKosti == 1); // bitince YINE kostu (nesil-guard gerekcesi) } // ---- Kuyruktayken iptal → is HIC kosmaz, bitince de kosmaz ------------------ // (isciDongusu is'i cekince once iptal bayragina bakar: is lambda'si atlanir, // durum=Iptal → pompala bitince'yi cagirmaz. Ilk yazimda "worker lambda iptali // gorur" varsayilmisti — gercek davranis daha iyi: lambda hic baslamaz.) FIKO_TEST(gorev_kuyrukta_iptal_is_kosmaz) { GorevSistemi g(1); OlayGunlugu o; std::atomic engelle{true}; std::atomic isKostu{false}; int bitinceKosti = 0; // Ilk is: worker'i mesgul tut → ikinci is kuyrukta beklerken iptal edilir. g.kuyrukla("blok", [&](GorevBaglam&) { const auto t0 = std::chrono::steady_clock::now(); while (engelle.load() && std::chrono::duration(std::chrono::steady_clock::now() - t0) .count() < 5000) std::this_thread::sleep_for(std::chrono::milliseconds(1)); }); const u64 k2 = g.kuyrukla("iptalli", [&](GorevBaglam&) { isKostu = true; }, [&] { ++bitinceKosti; }); g.iptalEt(k2); // is daha baslamadan iptal istendi engelle = false; // blok isini serbest birak pompalaBekle(g, o); FIKO_KONTROL(!isKostu.load()); // is lambda'si hic baslamadi FIKO_KONTROL(bitinceKosti == 0); // bitince de kosmadi (Iptal yolu) } // ---- Hata: hataAyarla → bitince KOSMAZ -------------------------------------- FIKO_TEST(gorev_hata_bitince_kosmaz) { GorevSistemi g(1); OlayGunlugu o; int bitinceKosti = 0; g.kuyrukla("h", [&](GorevBaglam& gb) { gb.hataAyarla("kasitli"); }, [&] { ++bitinceKosti; }); pompalaBekle(g, o); FIKO_KONTROL(bitinceKosti == 0); FIKO_KONTROL(g.bosMu()); }