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

Unexpected (undefined?) behaviour when using ::to_future with a canceled continuable #63

Open
LanderN opened this issue Jan 9, 2023 · 1 comment
Labels

Comments

@LanderN
Copy link

LanderN commented Jan 9, 2023

@Naios


Commit Hash

f7f304e (4.2.1)

Expected Behavior

Calling .get() on an std::future obtained by applying cti::transforms::to_future() should result in an exception.

Actual Behavior

.get() returns without an exception, returning some (random?) value or crashing (probably undefined behaviour).

Steps to Reproduce

Run the following program:

#include <iostream>

#include <continuable/continuable.hpp>

enum Result { READY, EXCEPTION, CANCELLATION };

cti::continuable<int> get_result(Result type) {
  switch (type) {
  case READY:
    std::cout << "Creating ready continuable..." << std::endl;
    return cti::make_ready_continuable<int>(1);
  case EXCEPTION:
    std::cout << "Creating exceptional continuable..." << std::endl;
    return cti::make_exceptional_continuable<int>(
        std::make_exception_ptr(std::runtime_error("Exception!")));
  case CANCELLATION:
  default:
    std::cout << "Creating cancelling continuable..." << std::endl;
    return cti::make_cancelling_continuable<int>();
    break;
  }
}

void test(Result type) {
  auto cti_value = get_result(type);
  auto future = std::move(cti_value).apply(cti::transforms::to_future());

  if (!future.valid()) {
    std::cout << "Future not valid!" << std::endl;
    exit(1);
  }

  future.wait();
  try {
    if (!future.valid()) {
      std::cout << "Future not valid!" << std::endl;
      exit(1);
    }
    auto value = future.get();
    std::cout << "Result is a value: " << value << "\n" << std::endl;
    // Do something with the value
  } catch (...) {
    std::cout << "Result is an exception!\n" << std::endl;
    // Do something with the exception
  }
}

int main() {
  test(READY);
  test(EXCEPTION);
  test(CANCELLATION);
}

Output (on my system):

Creating ready continuable...
Result is a value: 1

Creating exceptional continuable...
Result is an exception!

Creating cancelling continuable...
Result is a value: 1

I'm not sure what the expected behaviour is when calling .get() on a "cancelled" future, but it probably shouldn't return 1 in this case. Maybe this use case is unsupported? In that case, I would expect this to be reflected in the documentation.

Your Environment

  • OS: Arch Linux
  • Compiler and version: GCC 12.2.0
  • Standard library (if non default): glibc
@Naios Naios added the bug label Jan 10, 2023
@Naios
Copy link
Owner

Naios commented Jan 10, 2023

Thanks for your report.

It might be possible that to_future is missing the correct logic for the cancellation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants