Skip to content

Commit 4c7990f

Browse files
committed
Use std::optional<LockedStream> to avoid exposing mutex
1 parent 979abb7 commit 4c7990f

File tree

3 files changed

+31
-11
lines changed

3 files changed

+31
-11
lines changed

lldb/include/lldb/Host/Editline.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,9 @@ class Editline {
397397
FILE *m_input_file;
398398
lldb::LockableStreamFileSP m_output_stream_sp;
399399
lldb::LockableStreamFileSP m_error_stream_sp;
400+
401+
std::optional<LockedStreamFile> m_locked_output;
402+
400403
ConnectionFileDescriptor m_input_connection;
401404

402405
IsInputCompleteCallbackType m_is_input_complete_callback;

lldb/include/lldb/Host/StreamFile.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,16 @@ class LockedStreamFile : public StreamFile {
6060
public:
6161
~LockedStreamFile() { Flush(); }
6262

63+
LockedStreamFile(LockedStreamFile &&other)
64+
: StreamFile(other.m_file_sp), m_lock(std::move(other.m_lock)) {}
65+
6366
private:
6467
LockedStreamFile(std::shared_ptr<File> file, std::recursive_mutex &mutex)
65-
: StreamFile(file), m_guard(mutex) {}
68+
: StreamFile(file), m_lock(mutex) {}
6669

6770
friend class LockableStreamFile;
6871

69-
std::lock_guard<std::recursive_mutex> m_guard;
72+
std::unique_lock<std::recursive_mutex> m_lock;
7073
};
7174

7275
class LockableStreamFile {
@@ -92,8 +95,6 @@ class LockableStreamFile {
9295
std::shared_ptr<File> GetUnlockedFileSP() { return m_file_sp; }
9396
/// @}
9497

95-
Mutex &GetMutex() { return m_mutex; }
96-
9798
protected:
9899
std::shared_ptr<File> m_file_sp;
99100
Mutex &m_mutex;

lldb/source/Host/common/Editline.cpp

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,19 @@ using namespace lldb_private::line_editor;
7979

8080
#endif // #if LLDB_EDITLINE_USE_WCHAR
8181

82+
template <typename T> class ScopedOptional {
83+
public:
84+
template <typename... Args>
85+
ScopedOptional(std::optional<T> &optional, Args &&...args)
86+
: m_optional(optional) {
87+
m_optional.emplace(std::forward<Args>(args)...);
88+
}
89+
~ScopedOptional() { m_optional.reset(); }
90+
91+
private:
92+
std::optional<T> &m_optional;
93+
};
94+
8295
bool IsOnlySpaces(const EditLineStringType &content) {
8396
for (wchar_t ch : content) {
8497
if (ch != EditLineCharType(' '))
@@ -541,9 +554,10 @@ int Editline::GetCharacter(EditLineGetCharType *c) {
541554
// Paint a ANSI formatted version of the desired prompt over the version
542555
// libedit draws. (will only be requested if colors are supported)
543556
if (m_needs_prompt_repaint) {
544-
LockedStreamFile locked_stream = m_output_stream_sp->Lock();
557+
ScopedOptional<LockedStreamFile> scope(m_locked_output,
558+
m_output_stream_sp->Lock());
545559
MoveCursor(CursorLocation::EditingCursor, CursorLocation::EditingPrompt);
546-
fprintf(locked_stream.GetFile().GetStream(),
560+
fprintf(m_locked_output->GetFile().GetStream(),
547561
"%s"
548562
"%s"
549563
"%s",
@@ -581,10 +595,10 @@ int Editline::GetCharacter(EditLineGetCharType *c) {
581595
// indefinitely. This gives a chance for someone to interrupt us. After
582596
// Read returns, immediately lock the mutex again and check if we were
583597
// interrupted.
584-
m_output_stream_sp->GetMutex().unlock();
598+
m_locked_output.reset();
585599
int read_count =
586600
m_input_connection.Read(&ch, 1, std::nullopt, status, nullptr);
587-
m_output_stream_sp->GetMutex().lock();
601+
m_locked_output.emplace(m_output_stream_sp->Lock());
588602
if (m_editor_status == EditorStatus::Interrupted) {
589603
while (read_count > 0 && status == lldb::eConnectionStatusSuccess)
590604
read_count =
@@ -1599,7 +1613,8 @@ bool Editline::GetLine(std::string &line, bool &interrupted) {
15991613
m_input_lines = std::vector<EditLineStringType>();
16001614
m_input_lines.insert(m_input_lines.begin(), EditLineConstString(""));
16011615

1602-
LockedStreamFile locked_stream = m_output_stream_sp->Lock();
1616+
ScopedOptional<LockedStreamFile> scope(m_locked_output,
1617+
m_output_stream_sp->Lock());
16031618

16041619
lldbassert(m_editor_status != EditorStatus::Editing);
16051620
if (m_editor_status == EditorStatus::Interrupted) {
@@ -1619,7 +1634,7 @@ bool Editline::GetLine(std::string &line, bool &interrupted) {
16191634
interrupted = m_editor_status == EditorStatus::Interrupted;
16201635
if (!interrupted) {
16211636
if (input == nullptr) {
1622-
fprintf(locked_stream.GetFile().GetStream(), "\n");
1637+
fprintf(m_locked_output->GetFile().GetStream(), "\n");
16231638
m_editor_status = EditorStatus::EndOfInput;
16241639
} else {
16251640
m_history_sp->Enter(input);
@@ -1644,7 +1659,8 @@ bool Editline::GetLines(int first_line_number, StringList &lines,
16441659
m_input_lines = std::vector<EditLineStringType>();
16451660
m_input_lines.insert(m_input_lines.begin(), EditLineConstString(""));
16461661

1647-
LockedStreamFile locked_stream = m_output_stream_sp->Lock();
1662+
ScopedOptional<LockedStreamFile> scope(m_locked_output,
1663+
m_output_stream_sp->Lock());
16481664

16491665
// Begin the line editing loop
16501666
DisplayInput();

0 commit comments

Comments
 (0)