N3252 - A review of noexcept in the threads library
Document number: N3252=11-0022
Date: 2011-02-26
J. Daniel Garcia, Michael Wong
Project: Programming Language C++, Library Working Group
Reply To: josedaniel.garcia@uc3m.es

N3252 - A review of noexcept in the threads library

This paper studies possible changes to the Threads Library to make broad use of noexcept. The paper addresses National Body comments CH 16 and GB 60.

Changes in this paper are restricted to chapter 30 (threads library).

All changes in this paper are relative to N3225.

Discussion

Several swap() functions have been made noexcept as the are defined in terms of the corresponding noexcept member function.

In 30.4.1 mutex, recursive_mutex, timed_mutex and recursive_timed_mutex constructors have been made noexcept In section 30.6.1 some operations have been made noexcept to be consistent with the disgnostics library. In section 30.6.10 member function valid is not consistent with its definition in 30.6.10.1. It has been updated.

Proposed Wording

30.3 Threads [thread.threads]

After p. 1
namespace std {
  #define __STDCPP_THREADS__ __cplusplus

  class thread;

  void swap(thread& x, thread& y) noexcept;

  namespace this_thread {
    thread::id get_id() noexcept;
    void yield() noexcept;
    template <class Clock, class Duration>
      void sleep_until(const chrono::time_point<Clock, Duration>& abs_time) noexcept;
  template <class Rep, class Period>
    void sleep_for(const chrono::duration<Rep, Period>& rel_time) noexcept;
  }
}

30.3.1.7 thread specialized algorithms [thread.thread.algorithm]

Before p.1
void swap(thread& x, thread& y) noexcept;

30.4.1.2.1 Class mutex [thread.mutex.class]

Before p. 1
namespace std {
  class mutex {
  public:
    constexpr mutex() noexcept;
    ~mutex();

    mutex(const mutex&) = delete;
    mutex& operator=(const mutex&) = delete;

    void lock();
    bool try_lock() noexcept;
    void unlock() noexcept;

    typedef implementation-defined native_handle_type; // See 30.2.3
    native_handle_type native_handle(); // See 30.2.3
  };
}

30.4.1.2.2 Class recursive_mutex [thread.mutex.recursive]

Before p.1
namespace std {
  class recursive_mutex {
  public:
    recursive_mutex() noexcept;
    ~recursive_mutex();

    recursive_mutex(const recursive_mutex&) = delete;
    recursive_mutex& operator=(const recursive_mutex&) = delete;

    void lock();
    bool try_lock() noexcept;
    void unlock() noexcept;

    typedef implementation-defined native_handle_type; // See 30.2.3
    native_handle_type native_handle(); // See 30.2.3
  };
}

30.4.1.3.1 Class timed_mutex [thread.timedmutex.class]

Before p. 1
namespace std {
  class timed_mutex {
  public:
    timed_mutex() noexcept;
    ~timed_mutex();

    timed_mutex(const timed_mutex&) = delete;
    timed_mutex& operator=(const timed_mutex&) = delete;

    void lock();
    bool try_lock();
    template <class Rep, class Period>
      bool try_lock_for(const chrono::duration<Rep, Period>& rel_time) noexcept;
    template <class Clock, class Duration>
      bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time) noexcept;
    void unlock();

    typedef implementation-defined native_handle_type; // See 30.2.3
    native_handle_type native_handle(); // See 30.2.3
  };
}

30.4.1.3.2 Class recursive_timed_mutex [thread.timedmutex.recursive]

Before p. 1
namespace std {
  class recursive_timed_mutex {
  public:
    recursive_timed_mutex() noexcept;
    ~recursive_timed_mutex();

    recursive_timed_mutex(const recursive_timed_mutex&) = delete;
    recursive_timed_mutex& operator=(const recursive_timed_mutex&) = delete;

    void lock();
    bool try_lock();
    template <class Rep, class Period>
      bool try_lock_for(const chrono::duration<Rep, Period>& rel_time) noexcept;
    template <class Clock, class Duration>
      bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time) noexcept;
    void unlock();

    typedef implementation-defined native_handle_type; // See 30.2.3
    native_handle_type native_handle(); // See 30.2.3
  };
}

30.6.2 Error handling

Before p.1
const error_category& future_category() noexcept;
After p. 2
error_code make_error_code(future_errc e) noexcept;
After p. 3
error_condition make_error_condition(future_errc e) noexcept;

30.6.5 Class template promise [futures.promise]

After p. 27
template <class R>
  void swap(promise<R>& x, promise<R>& y) noexcept;

30.6.10 Class template packaged_task [futures.task]

After p.2
namespace std {
template<class R, class... ArgTypes>
class packaged_task<R(ArgTypes...)> {
public:
...
  bool valid() const noexcept;
...