|
5 | 5 |
|
6 | 6 | All rights reserved. Use of this source code is governed by a
|
7 | 7 | BSD-style license that can be found in the LICENSE file.
|
| 8 | +
|
| 9 | + WARNING: The implementation in this file is NOT thread safe. Multiple |
| 10 | + threads writing to a redirected ostream concurrently cause data races |
| 11 | + and potentially buffer overflows. Therefore it is currrently a requirement |
| 12 | + that all (possibly) concurrent redirected ostream writes are protected by |
| 13 | + a mutex. |
| 14 | + #HelpAppreciated: Work on iostream.h thread safety. |
| 15 | + For more background see the discussions under |
| 16 | + https://github.com/pybind/pybind11/pull/2982 and |
| 17 | + https://github.com/pybind/pybind11/pull/2995. |
8 | 18 | */
|
9 | 19 |
|
10 | 20 | #pragma once
|
@@ -85,30 +95,25 @@ class pythonbuf : public std::streambuf {
|
85 | 95 | return remainder;
|
86 | 96 | }
|
87 | 97 |
|
88 |
| - // This function must be non-virtual to be called in a destructor. If the |
89 |
| - // rare MSVC test failure shows up with this version, then this should be |
90 |
| - // simplified to a fully qualified call. |
| 98 | + // This function must be non-virtual to be called in a destructor. |
91 | 99 | int _sync() {
|
92 | 100 | if (pbase() != pptr()) { // If buffer is not empty
|
93 | 101 | gil_scoped_acquire tmp;
|
94 |
| - // Placed inside gil_scoped_acquire as a mutex to avoid a race. |
95 |
| - if (pbase() != pptr()) { // Check again under the lock |
96 |
| - // This subtraction cannot be negative, so dropping the sign. |
97 |
| - auto size = static_cast<size_t>(pptr() - pbase()); |
98 |
| - size_t remainder = utf8_remainder(); |
99 |
| - |
100 |
| - if (size > remainder) { |
101 |
| - str line(pbase(), size - remainder); |
102 |
| - pywrite(line); |
103 |
| - pyflush(); |
104 |
| - } |
105 |
| - |
106 |
| - // Copy the remainder at the end of the buffer to the beginning: |
107 |
| - if (remainder > 0) |
108 |
| - std::memmove(pbase(), pptr() - remainder, remainder); |
109 |
| - setp(pbase(), epptr()); |
110 |
| - pbump(static_cast<int>(remainder)); |
| 102 | + // This subtraction cannot be negative, so dropping the sign. |
| 103 | + auto size = static_cast<size_t>(pptr() - pbase()); |
| 104 | + size_t remainder = utf8_remainder(); |
| 105 | + |
| 106 | + if (size > remainder) { |
| 107 | + str line(pbase(), size - remainder); |
| 108 | + pywrite(line); |
| 109 | + pyflush(); |
111 | 110 | }
|
| 111 | + |
| 112 | + // Copy the remainder at the end of the buffer to the beginning: |
| 113 | + if (remainder > 0) |
| 114 | + std::memmove(pbase(), pptr() - remainder, remainder); |
| 115 | + setp(pbase(), epptr()); |
| 116 | + pbump(static_cast<int>(remainder)); |
112 | 117 | }
|
113 | 118 | return 0;
|
114 | 119 | }
|
|
0 commit comments