title: Synchronized and withContext
body: <p>I have the following class:</p>
  <pre><code>class SdkWrapper(private val sdk: Sdk) {
  
      private var inited = false
  
      suspend fun doSomething() = withContext(Dispatchers.IO) {
          if (inited.not()) init()
          useSdk()
      }
          
      private fun init() {
          // takes a long time
          sdk.init()
          inited = true
      }
  
      // has to be done asynchronously
      // sdk.init() has to have been called before using this
      private fun useSdk() {
  
      }
  
  }
  
  class Sdk {
      // must only be done once
      fun init() {}
  }
  </code></pre>
  <p>Before I can do <code>useSdk()</code>, I must call <code>sdk.init()</code>, but <code>sdk.init()</code> must only be called once, not more.</p>
  <p>With my current solution, if <code>doSomething</code> is called twice quickly (the second time happening while <code>sdk.init()</code> still running), I would call <code>sdk.init()</code> twice, because <code>inited: Boolean</code> is still <code>false</code>.</p>
  <p>If I move the assignment of <code>inited</code> up like:</p>
  <pre><code>private fun init() {
      inited = true
      sdk.init()
  }
  </code></pre>
  <p>and <code>doSomething()</code> is called twice rapidly, the second call would use the sdk before its' <code>init()</code> has been done.</p>
  <p>I tried to solve this with:</p>
  <pre><code>suspend fun doSomething() = synchronized(this){
      withContext(Dispatchers.IO) {
          if (inited.not()) init()
          useSdk()
      }
  }
  </code></pre>
  <p>but receive an error in IntelliJ:</p>
  <blockquote>
  <p>the withContext suspension point is inside a critical section</p>
  </blockquote>
  <p>I assume that <code>synchronized</code> wouldn't work here anyway, because we move off the main thread and <code>doSomething()</code> is completed while the <code>withContext</code> block is still running?</p>
  <p>How can I solve the problem at hand which basically is: <code>doSomething()</code> should only run once at a time?</p>