copper icon indicating copy to clipboard operation
copper copied to clipboard

close cannot close all pops...

Open xbyl1234 opened this issue 2 years ago • 3 comments

copper::chan channel;

void ch1() { printf("ch1 start\n"); for (const auto& item : channel) { printf("%s\n", item.c_str()); } printf("ch1 end\n"); }

void ch2(copper::chan& channel) { printf("ch2 start\n");

channel.push("2");

printf("ch2 end\n");

}

void aa() { for (size_t i = 0; i < 5; i++) { new std::thread(& { ch1(); });

}
//sleep(1000 * 2);
std::thread* my_thread2 = new std::thread([&]() {
	ch2(channel);
	channel.close();
	}); 

}

xbyl1234 avatar Jun 26 '23 11:06 xbyl1234

Hey. Could you add three backticks ` before and after your example and properly format it so it becomes redable?

Also, what exactly is the code supposed to show?

atollk avatar Jun 26 '23 19:06 atollk

hey, Reply so quickly

use this code the thread is always in the join ,if ~channel() called will assert error

	while (true)
	{
		copper::buffered_channel<string> channel;
		vector<thread*> ths;
		for (size_t i = 0; i < 5; i++)
		{
			ths.push_back(new std::thread([&]() {
				for (auto& item : channel)
				{

				}
				}));
		}
		channel.close();
		for (auto item : ths)
		{
			item->join();
		}
		printf("next");
	}

This is my revised code, It seems to work.

        
        void close() {
            const auto lock = std::lock_guard<_detail::channel_mutex_t>(this->_mutex);
            if (this->_open) {
                this->_open = false;
                for (auto *popper: this->_waiting_pops) {
                    popper->channel_closed();
                }
                this->_waiting_pops.clear();
                for (auto *pusher: this->_waiting_pushes) {
                    pusher->channel_closed();
                }
                this->_waiting_pushes.clear();
            }
        }
 
            void channel_closed() {
                const auto lock = std::lock_guard(this->_parent->mutex);
//#if __cpp_lib_erase_if >= 202002L
//                std::erase(this->_channel->_waiting_pops, this);
//#else
//                this->_channel->_waiting_pops.erase(
//                        std::remove(this->_channel->_waiting_pops.begin(),
//                                    this->_channel->_waiting_pops.end(), this),
//                        this->_channel->_waiting_pops.end());
//#endif
                this->_active = false;
                this->_parent->open_op_channels -= 1;
                this->_parent->cv.notify_all();
            }

xbyl1234 avatar Jun 27 '23 03:06 xbyl1234

I added a branch with a regression test and I confirm that I encounter a similar issue. But for me, the assertions don't fail; instead, I run into a deadlock. Your change also doesn't fix that. I'll see what I can do but so far I don't really have an idea. If you have more information or ideas, that might help.

atollk avatar Jul 15 '23 00:07 atollk