Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

close cannot close all pops... #23

Open
xbyl1234 opened this issue Jun 26, 2023 · 3 comments
Open

close cannot close all pops... #23

xbyl1234 opened this issue Jun 26, 2023 · 3 comments
Labels
bug Something isn't working

Comments

@xbyl1234
Copy link

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 xbyl1234 added the bug Something isn't working label Jun 26, 2023
@atollk
Copy link
Owner

atollk commented Jun 26, 2023

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?

@xbyl1234
Copy link
Author

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();
            }

@atollk
Copy link
Owner

atollk commented Jul 15, 2023

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants