Youtube details
===============

I have been browsing youtube to try and develop my understanding of C++ multithread support with mutex and condition variables.

I came across this video. **Skip to time 6:30 to see what I am currently looking at.** (A page of code.)

* <https://www.youtube.com/watch?v=eh_9zUNmTig>

I believe there is a mistake in the code, but I wanted to check. It could just as well be that I don't understand something.

Question
========

The author states that `std::unique_lock` locks the mutex on creation. Meaning that there is no need to call

```
unique_lock<mutex> lock(m)
lock.lock(); // this is wrong, because unique_lock already locked the mutex

```

after creating a `unique_lock` object.

I *assume* although I do not know for certain, that `unique_lock` will release the mutex lock on destruction. (Aka when it goes out of scope.)

---

*Can it also be unlocked manually by calling*

```
lock.unlock()

```

*?* From the [documentation](https://en.cppreference.com/w/cpp/thread/unique_lock) it appears there is no such unlock function. It looks like `unique_lock` is therefore the same as `scoped_lock`? But again, I'm assuming this isn't the case and there's some other information I am missing.

---

*Continuing...* The author has a function which looks like this:

```
void addMoney(int money)
{
    std::lock_guard<mutex> lg(m); // lock_guard being used interchangably with unique_lock - why?
    balance += money; // adding to global variable

    cv.notify_one(); // error here
                     // the lock_guard is still in scope
                     // the mutex is still locked
                     // calling notify_one() may cause the sleeping thread to wake up
                     // check if the mutex is still locked (which it might be if the
                     // destructor for lg hasn't finished running)
                     // and then go back to sleep
                     // meaning this line of code may have no effect
                     // it is undefined behaviour
}

```

I have anotated where I believe there is an error. I think this function causes undefined behaviour, because the `lock_guard` is still in scope, and therefore the mutex might be locked.

*Effectively it is a race condition:*

* *If `addMoney()` ends before the other function begins, we are ok*
* *If the other function `withdrawMoney()` checks the lock (`cv.wait()`) before `addMoney()` exits then the program breaks, and remains in a locked state*

For completeness here is the other function:

```
void withdrawMoney(int money)
{
    std::unique_lock<mutex> ul(m); // unique_lock instead of scoped_lock? why?
    cv.wait(ul, []{return balance != 0;});
    // some more stuff omitted
}

```

Summary
=======

There are a couple of points I have raised

* Most importantly the race condition
* Of secondary importance, why are two different things (`lock_guard` and `unique_lock`) being used to do what appears to be *the same thing* (performing the same function)