| 690 | } |
| 691 | |
| 692 | void Server::scanNextPlugin(const String& id, const String& name, const String& fmt, int srvId, |
| 693 | std::function<void(const String&)> onShellPlugin, bool secondRun) { |
| 694 | traceScope(); |
| 695 | String fileFmt = id; |
| 696 | fileFmt << "|" << fmt; |
| 697 | ChildProcess proc; |
| 698 | StringArray args; |
| 699 | args.add(File::getSpecialLocation(File::currentExecutableFile).getFullPathName()); |
| 700 | args.addArray({"-scan", fileFmt}); |
| 701 | args.addArray({"-id", String(srvId)}); |
| 702 | if (secondRun) { |
| 703 | args.add("-secondrun"); |
| 704 | } |
| 705 | String pipeName = "audiogridderscan." + String(srvId); |
| 706 | NamedPipe pipe; |
| 707 | if (!pipe.createNewPipe(pipeName)) { |
| 708 | logln("warning: can't open pipe " << pipeName); |
| 709 | } |
| 710 | bool blacklist = false; |
| 711 | if (proc.start(args)) { |
| 712 | const int secondsPerPlugin = 30; |
| 713 | std::atomic_int secondsLeft{secondsPerPlugin}; |
| 714 | |
| 715 | FnThread outputReader( |
| 716 | [this, &pipe, &proc, &secondsLeft, name, secs = secondsPerPlugin, onShellPlugin] { |
| 717 | std::vector<char> buf(256); |
| 718 | std::unique_ptr<TimeStatistic::Timeout> loadTimeout; |
| 719 | String lastShellName; |
| 720 | while (proc.isRunning() && !currentThreadShouldExit()) { |
| 721 | ScanPipeHdr hdr; |
| 722 | if (pipe.read(&hdr, sizeof(hdr), 100) == sizeof(hdr)) { |
| 723 | switch (hdr.type) { |
| 724 | case ScanPipeHdr::LOAD_START: |
| 725 | loadTimeout = std::make_unique<TimeStatistic::Timeout>(5000); |
| 726 | break; |
| 727 | case ScanPipeHdr::LOAD_FINISHED: |
| 728 | loadTimeout.reset(); |
| 729 | break; |
| 730 | case ScanPipeHdr::SHELL: |
| 731 | if (pipe.read(buf.data(), hdr.len, 1000) == hdr.len) { |
| 732 | buf[(size_t)hdr.len] = 0; |
| 733 | lastShellName = buf.data(); |
| 734 | // let the scanner know, that the current plugin is a shell and has plugins inside |
| 735 | onShellPlugin(lastShellName); |
| 736 | // increase the timeout as there might be mutliple plugins per shell |
| 737 | secondsLeft = secs; |
| 738 | logln(" -> shell plugin: " << lastShellName); |
| 739 | } |
| 740 | break; |
| 741 | } |
| 742 | } |
| 743 | if (nullptr != loadTimeout && loadTimeout->getMillisecondsLeft() <= 0) { |
| 744 | logln("error: load timeout for '" << (lastShellName.isNotEmpty() ? lastShellName : name) |
| 745 | << "', killing process"); |
| 746 | proc.kill(); |
| 747 | loadTimeout.reset(); |
| 748 | } |
| 749 | } |
nothing calls this directly
no test coverage detected