We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Using SunPy in two threads sometimes crashes when creating config
I test HelioPy on two threads at the same time, and when it comes to importing SunPy the following error happens sporadically:

```
heliopy\coordinates\test\test_transformations.py:1: in <module>
    import heliopy.coordinates.frames as frames
heliopy\coordinates\frames.py:19: in <module>
    import sunpy.coordinates.sun
c:\hostedtoolcache\windows\python\3.6.8\x64\lib\site-packages\sunpy\__init__.py:47: in <module>
    config = load_config()
c:\hostedtoolcache\windows\python\3.6.8\x64\lib\site-packages\sunpy\util\config.py:30: in load_config
    config_files = _find_config_files()
c:\hostedtoolcache\windows\python\3.6.8\x64\lib\site-packages\sunpy\util\config.py:69: in _find_config_files
    config_path = Path(_get_user_configdir())
c:\hostedtoolcache\windows\python\3.6.8\x64\lib\site-packages\sunpy\util\config.py:137: in _get_user_configdir
    if not _is_writable_dir(configdir):
c:\hostedtoolcache\windows\python\3.6.8\x64\lib\site-packages\sunpy\util\config.py:123: in _is_writable_dir
    Path(p).mkdir(parents=True)
c:\hostedtoolcache\windows\python\3.6.8\x64\lib\pathlib.py:1253: in mkdir
    self.mkdir(mode, parents=False, exist_ok=exist_ok)
c:\hostedtoolcache\windows\python\3.6.8\x64\lib\pathlib.py:1248: in mkdir
    self._accessor.mkdir(self, mode)
c:\hostedtoolcache\windows\python\3.6.8\x64\lib\pathlib.py:387: in wrapped
    return strfunc(str(pathobj), *args)
E   FileExistsError: [WinError 183] Cannot create a file when that file already exists: 'C:\\Users\\VssAdministrator\\AppData\\Local\\sunpy\\sunpy'
```

I think the solution is to change `Path(p).mkdir(parents=True)` to `Path(p).mkdir(parents=True, exist_okay=True)`

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `sunpy/util/config.py`
Content:
```
1 """
2 This module provides SunPy's configuration file functionality.
3 """
4 import os
5 import configparser
6 from pathlib import Path
7 
8 import sunpy
9 from sunpy.extern.appdirs import AppDirs
10 
11 __all__ = ['load_config', 'print_config', 'CONFIG_DIR']
12 
13 # This is to avoid creating a new config dir for each new dev version.
14 # We use AppDirs to locate and create the config directory.
15 dirs = AppDirs("sunpy", "sunpy")
16 # Default one set by AppDirs
17 CONFIG_DIR = dirs.user_config_dir
18 
19 
20 def load_config():
21     """
22     Read the "sunpyrc" configuration file.
23 
24     If one does not exists in the user's home directory then read in the
25     defaults from "sunpy/data/sunpyrc".
26     """
27     config = configparser.RawConfigParser()
28 
29     # Get locations of SunPy configuration files to be loaded
30     config_files = _find_config_files()
31 
32     # Read in configuration files
33     config.read(config_files)
34 
35     # Specify the working directory as a default so that the user's home
36     # directory can be located in an OS-independent manner
37     if not config.has_option('general', 'working_dir'):
38         config.set('general', 'working_dir', str(Path.home() / "sunpy"))
39 
40     # Specify the database url as a default so that the user's home
41     # directory can be located in an OS-independent manner
42     if not config.has_option('database', 'url'):
43         config.set('database', 'url', "sqlite:///" + str(Path.home() / "sunpy" / "sunpydb.sqlite"))
44 
45     # Set the download_dir to be relative to the working_dir
46     working_dir = Path(config.get('general', 'working_dir'))
47     download_dir = Path(config.get('downloads', 'download_dir'))
48     sample_dir = config.get('downloads', 'sample_dir', fallback=dirs.user_data_dir)
49     config.set('downloads', 'sample_dir', Path(sample_dir).expanduser().resolve().as_posix())
50     config.set('downloads', 'download_dir', (working_dir / download_dir).expanduser().resolve().as_posix())
51 
52     return config
53 
54 
55 def _find_config_files():
56     """
57     Finds locations of SunPy configuration files.
58     """
59     config_files = []
60     config_filename = 'sunpyrc'
61 
62     # find default configuration file
63     module_dir = Path(sunpy.__file__).parent
64     config_files.append(str(module_dir / 'data' / 'sunpyrc'))
65 
66     # if a user configuration file exists, add that to list of files to read
67     # so that any values set there will override ones specified in the default
68     # config file
69     config_path = Path(_get_user_configdir())
70     if config_path.joinpath(config_filename).exists():
71         config_files.append(str(config_path.joinpath(config_filename)))
72 
73     return config_files
74 
75 
76 def get_and_create_download_dir():
77     """
78     Get the config of download directory and create one if not present.
79     """
80     download_dir = os.environ.get('SUNPY_DOWNLOADDIR')
81     if download_dir:
82         return download_dir
83 
84     download_dir = Path(sunpy.config.get('downloads', 'download_dir')).expanduser().resolve()
85     if not _is_writable_dir(download_dir):
86         raise RuntimeError(f'Could not write to SunPy downloads directory="{download_dir}"')
87 
88     return sunpy.config.get('downloads', 'download_dir')
89 
90 
91 def get_and_create_sample_dir():
92     """
93     Get the config of download directory and create one if not present.
94     """
95     sample_dir = Path(sunpy.config.get('downloads', 'sample_dir')).expanduser().resolve()
96     if not _is_writable_dir(sample_dir):
97         raise RuntimeError(f'Could not write to SunPy sample data directory="{sample_dir}"')
98 
99     return sunpy.config.get('downloads', 'sample_dir')
100 
101 
102 def print_config():
103     """
104     Print current configuration options.
105     """
106     print("FILES USED:")
107     for file_ in _find_config_files():
108         print("  " + file_)
109 
110     print("\nCONFIGURATION:")
111     for section in sunpy.config.sections():
112         print("  [{0}]".format(section))
113         for option in sunpy.config.options(section):
114             print("  {} = {}".format(option, sunpy.config.get(section, option)))
115         print("")
116 
117 
118 def _is_writable_dir(p):
119     """
120     Checks to see if a directory is writable.
121     """
122     if not Path(p).exists():
123         Path(p).mkdir(parents=True)
124     return Path(p).is_dir() and os.access(p, os.W_OK)
125 
126 
127 def _get_user_configdir():
128     """
129     Return the string representing the configuration dir.
130 
131     The default is set by "AppDirs" and can be accessed by importing
132     ``sunpy.util.config.CONFIG_DIR``. You can override this with the
133     "SUNPY_CONFIGDIR" environment variable.
134     """
135     configdir = os.environ.get('SUNPY_CONFIGDIR', CONFIG_DIR)
136 
137     if not _is_writable_dir(configdir):
138         raise RuntimeError(f'Could not write to SUNPY_CONFIGDIR="{configdir}"')
139     return configdir
140
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/sunpy/util/config.py b/sunpy/util/config.py
--- a/sunpy/util/config.py
+++ b/sunpy/util/config.py
@@ -119,9 +119,13 @@
     """
     Checks to see if a directory is writable.
     """
-    if not Path(p).exists():
-        Path(p).mkdir(parents=True)
-    return Path(p).is_dir() and os.access(p, os.W_OK)
+    # Worried about multiple threads creating the directory at the same time.
+    try:
+        Path(p).mkdir(parents=True, exist_ok=True)
+    except FileExistsError:  # raised if there's an existing file instead of a directory
+        return False
+    else:
+        return Path(p).is_dir() and os.access(p, os.W_OK)
 
 
 def _get_user_configdir():

{"golden_diff": "diff --git a/sunpy/util/config.py b/sunpy/util/config.py\n--- a/sunpy/util/config.py\n+++ b/sunpy/util/config.py\n@@ -119,9 +119,13 @@\n     \"\"\"\n     Checks to see if a directory is writable.\n     \"\"\"\n-    if not Path(p).exists():\n-        Path(p).mkdir(parents=True)\n-    return Path(p).is_dir() and os.access(p, os.W_OK)\n+    # Worried about multiple threads creating the directory at the same time.\n+    try:\n+        Path(p).mkdir(parents=True, exist_ok=True)\n+    except FileExistsError:  # raised if there's an existing file instead of a directory\n+        return False\n+    else:\n+        return Path(p).is_dir() and os.access(p, os.W_OK)\n \n \n def _get_user_configdir():\n", "issue": "Using SunPy in two threads sometimes crashes when creating config\nI test HelioPy on two threads at the same time, and when it comes to importing SunPy the following error happens sporadically:\r\n\r\n```\r\nheliopy\\coordinates\\test\\test_transformations.py:1: in <module>\r\n    import heliopy.coordinates.frames as frames\r\nheliopy\\coordinates\\frames.py:19: in <module>\r\n    import sunpy.coordinates.sun\r\nc:\\hostedtoolcache\\windows\\python\\3.6.8\\x64\\lib\\site-packages\\sunpy\\__init__.py:47: in <module>\r\n    config = load_config()\r\nc:\\hostedtoolcache\\windows\\python\\3.6.8\\x64\\lib\\site-packages\\sunpy\\util\\config.py:30: in load_config\r\n    config_files = _find_config_files()\r\nc:\\hostedtoolcache\\windows\\python\\3.6.8\\x64\\lib\\site-packages\\sunpy\\util\\config.py:69: in _find_config_files\r\n    config_path = Path(_get_user_configdir())\r\nc:\\hostedtoolcache\\windows\\python\\3.6.8\\x64\\lib\\site-packages\\sunpy\\util\\config.py:137: in _get_user_configdir\r\n    if not _is_writable_dir(configdir):\r\nc:\\hostedtoolcache\\windows\\python\\3.6.8\\x64\\lib\\site-packages\\sunpy\\util\\config.py:123: in _is_writable_dir\r\n    Path(p).mkdir(parents=True)\r\nc:\\hostedtoolcache\\windows\\python\\3.6.8\\x64\\lib\\pathlib.py:1253: in mkdir\r\n    self.mkdir(mode, parents=False, exist_ok=exist_ok)\r\nc:\\hostedtoolcache\\windows\\python\\3.6.8\\x64\\lib\\pathlib.py:1248: in mkdir\r\n    self._accessor.mkdir(self, mode)\r\nc:\\hostedtoolcache\\windows\\python\\3.6.8\\x64\\lib\\pathlib.py:387: in wrapped\r\n    return strfunc(str(pathobj), *args)\r\nE   FileExistsError: [WinError 183] Cannot create a file when that file already exists: 'C:\\\\Users\\\\VssAdministrator\\\\AppData\\\\Local\\\\sunpy\\\\sunpy'\r\n```\r\n\r\nI think the solution is to change `Path(p).mkdir(parents=True)` to `Path(p).mkdir(parents=True, exist_okay=True)`\n", "before_files": [{"content": "\"\"\"\nThis module provides SunPy's configuration file functionality.\n\"\"\"\nimport os\nimport configparser\nfrom pathlib import Path\n\nimport sunpy\nfrom sunpy.extern.appdirs import AppDirs\n\n__all__ = ['load_config', 'print_config', 'CONFIG_DIR']\n\n# This is to avoid creating a new config dir for each new dev version.\n# We use AppDirs to locate and create the config directory.\ndirs = AppDirs(\"sunpy\", \"sunpy\")\n# Default one set by AppDirs\nCONFIG_DIR = dirs.user_config_dir\n\n\ndef load_config():\n    \"\"\"\n    Read the \"sunpyrc\" configuration file.\n\n    If one does not exists in the user's home directory then read in the\n    defaults from \"sunpy/data/sunpyrc\".\n    \"\"\"\n    config = configparser.RawConfigParser()\n\n    # Get locations of SunPy configuration files to be loaded\n    config_files = _find_config_files()\n\n    # Read in configuration files\n    config.read(config_files)\n\n    # Specify the working directory as a default so that the user's home\n    # directory can be located in an OS-independent manner\n    if not config.has_option('general', 'working_dir'):\n        config.set('general', 'working_dir', str(Path.home() / \"sunpy\"))\n\n    # Specify the database url as a default so that the user's home\n    # directory can be located in an OS-independent manner\n    if not config.has_option('database', 'url'):\n        config.set('database', 'url', \"sqlite:///\" + str(Path.home() / \"sunpy\" / \"sunpydb.sqlite\"))\n\n    # Set the download_dir to be relative to the working_dir\n    working_dir = Path(config.get('general', 'working_dir'))\n    download_dir = Path(config.get('downloads', 'download_dir'))\n    sample_dir = config.get('downloads', 'sample_dir', fallback=dirs.user_data_dir)\n    config.set('downloads', 'sample_dir', Path(sample_dir).expanduser().resolve().as_posix())\n    config.set('downloads', 'download_dir', (working_dir / download_dir).expanduser().resolve().as_posix())\n\n    return config\n\n\ndef _find_config_files():\n    \"\"\"\n    Finds locations of SunPy configuration files.\n    \"\"\"\n    config_files = []\n    config_filename = 'sunpyrc'\n\n    # find default configuration file\n    module_dir = Path(sunpy.__file__).parent\n    config_files.append(str(module_dir / 'data' / 'sunpyrc'))\n\n    # if a user configuration file exists, add that to list of files to read\n    # so that any values set there will override ones specified in the default\n    # config file\n    config_path = Path(_get_user_configdir())\n    if config_path.joinpath(config_filename).exists():\n        config_files.append(str(config_path.joinpath(config_filename)))\n\n    return config_files\n\n\ndef get_and_create_download_dir():\n    \"\"\"\n    Get the config of download directory and create one if not present.\n    \"\"\"\n    download_dir = os.environ.get('SUNPY_DOWNLOADDIR')\n    if download_dir:\n        return download_dir\n\n    download_dir = Path(sunpy.config.get('downloads', 'download_dir')).expanduser().resolve()\n    if not _is_writable_dir(download_dir):\n        raise RuntimeError(f'Could not write to SunPy downloads directory=\"{download_dir}\"')\n\n    return sunpy.config.get('downloads', 'download_dir')\n\n\ndef get_and_create_sample_dir():\n    \"\"\"\n    Get the config of download directory and create one if not present.\n    \"\"\"\n    sample_dir = Path(sunpy.config.get('downloads', 'sample_dir')).expanduser().resolve()\n    if not _is_writable_dir(sample_dir):\n        raise RuntimeError(f'Could not write to SunPy sample data directory=\"{sample_dir}\"')\n\n    return sunpy.config.get('downloads', 'sample_dir')\n\n\ndef print_config():\n    \"\"\"\n    Print current configuration options.\n    \"\"\"\n    print(\"FILES USED:\")\n    for file_ in _find_config_files():\n        print(\"  \" + file_)\n\n    print(\"\\nCONFIGURATION:\")\n    for section in sunpy.config.sections():\n        print(\"  [{0}]\".format(section))\n        for option in sunpy.config.options(section):\n            print(\"  {} = {}\".format(option, sunpy.config.get(section, option)))\n        print(\"\")\n\n\ndef _is_writable_dir(p):\n    \"\"\"\n    Checks to see if a directory is writable.\n    \"\"\"\n    if not Path(p).exists():\n        Path(p).mkdir(parents=True)\n    return Path(p).is_dir() and os.access(p, os.W_OK)\n\n\ndef _get_user_configdir():\n    \"\"\"\n    Return the string representing the configuration dir.\n\n    The default is set by \"AppDirs\" and can be accessed by importing\n    ``sunpy.util.config.CONFIG_DIR``. You can override this with the\n    \"SUNPY_CONFIGDIR\" environment variable.\n    \"\"\"\n    configdir = os.environ.get('SUNPY_CONFIGDIR', CONFIG_DIR)\n\n    if not _is_writable_dir(configdir):\n        raise RuntimeError(f'Could not write to SUNPY_CONFIGDIR=\"{configdir}\"')\n    return configdir\n", "path": "sunpy/util/config.py"}], "after_files": [{"content": "\"\"\"\nThis module provides SunPy's configuration file functionality.\n\"\"\"\nimport os\nimport configparser\nfrom pathlib import Path\n\nimport sunpy\nfrom sunpy.extern.appdirs import AppDirs\n\n__all__ = ['load_config', 'print_config', 'CONFIG_DIR']\n\n# This is to avoid creating a new config dir for each new dev version.\n# We use AppDirs to locate and create the config directory.\ndirs = AppDirs(\"sunpy\", \"sunpy\")\n# Default one set by AppDirs\nCONFIG_DIR = dirs.user_config_dir\n\n\ndef load_config():\n    \"\"\"\n    Read the \"sunpyrc\" configuration file.\n\n    If one does not exists in the user's home directory then read in the\n    defaults from \"sunpy/data/sunpyrc\".\n    \"\"\"\n    config = configparser.RawConfigParser()\n\n    # Get locations of SunPy configuration files to be loaded\n    config_files = _find_config_files()\n\n    # Read in configuration files\n    config.read(config_files)\n\n    # Specify the working directory as a default so that the user's home\n    # directory can be located in an OS-independent manner\n    if not config.has_option('general', 'working_dir'):\n        config.set('general', 'working_dir', str(Path.home() / \"sunpy\"))\n\n    # Specify the database url as a default so that the user's home\n    # directory can be located in an OS-independent manner\n    if not config.has_option('database', 'url'):\n        config.set('database', 'url', \"sqlite:///\" + str(Path.home() / \"sunpy\" / \"sunpydb.sqlite\"))\n\n    # Set the download_dir to be relative to the working_dir\n    working_dir = Path(config.get('general', 'working_dir'))\n    download_dir = Path(config.get('downloads', 'download_dir'))\n    sample_dir = config.get('downloads', 'sample_dir', fallback=dirs.user_data_dir)\n    config.set('downloads', 'sample_dir', Path(sample_dir).expanduser().resolve().as_posix())\n    config.set('downloads', 'download_dir', (working_dir / download_dir).expanduser().resolve().as_posix())\n\n    return config\n\n\ndef _find_config_files():\n    \"\"\"\n    Finds locations of SunPy configuration files.\n    \"\"\"\n    config_files = []\n    config_filename = 'sunpyrc'\n\n    # find default configuration file\n    module_dir = Path(sunpy.__file__).parent\n    config_files.append(str(module_dir / 'data' / 'sunpyrc'))\n\n    # if a user configuration file exists, add that to list of files to read\n    # so that any values set there will override ones specified in the default\n    # config file\n    config_path = Path(_get_user_configdir())\n    if config_path.joinpath(config_filename).exists():\n        config_files.append(str(config_path.joinpath(config_filename)))\n\n    return config_files\n\n\ndef get_and_create_download_dir():\n    \"\"\"\n    Get the config of download directory and create one if not present.\n    \"\"\"\n    download_dir = os.environ.get('SUNPY_DOWNLOADDIR')\n    if download_dir:\n        return download_dir\n\n    download_dir = Path(sunpy.config.get('downloads', 'download_dir')).expanduser().resolve()\n    if not _is_writable_dir(download_dir):\n        raise RuntimeError(f'Could not write to SunPy downloads directory=\"{download_dir}\"')\n\n    return sunpy.config.get('downloads', 'download_dir')\n\n\ndef get_and_create_sample_dir():\n    \"\"\"\n    Get the config of download directory and create one if not present.\n    \"\"\"\n    sample_dir = Path(sunpy.config.get('downloads', 'sample_dir')).expanduser().resolve()\n    if not _is_writable_dir(sample_dir):\n        raise RuntimeError(f'Could not write to SunPy sample data directory=\"{sample_dir}\"')\n\n    return sunpy.config.get('downloads', 'sample_dir')\n\n\ndef print_config():\n    \"\"\"\n    Print current configuration options.\n    \"\"\"\n    print(\"FILES USED:\")\n    for file_ in _find_config_files():\n        print(\"  \" + file_)\n\n    print(\"\\nCONFIGURATION:\")\n    for section in sunpy.config.sections():\n        print(\"  [{0}]\".format(section))\n        for option in sunpy.config.options(section):\n            print(\"  {} = {}\".format(option, sunpy.config.get(section, option)))\n        print(\"\")\n\n\ndef _is_writable_dir(p):\n    \"\"\"\n    Checks to see if a directory is writable.\n    \"\"\"\n    # Worried about multiple threads creating the directory at the same time.\n    try:\n        Path(p).mkdir(parents=True, exist_ok=True)\n    except FileExistsError:  # raised if there's an existing file instead of a directory\n        return False\n    else:\n        return Path(p).is_dir() and os.access(p, os.W_OK)\n\n\ndef _get_user_configdir():\n    \"\"\"\n    Return the string representing the configuration dir.\n\n    The default is set by \"AppDirs\" and can be accessed by importing\n    ``sunpy.util.config.CONFIG_DIR``. You can override this with the\n    \"SUNPY_CONFIGDIR\" environment variable.\n    \"\"\"\n    configdir = os.environ.get('SUNPY_CONFIGDIR', CONFIG_DIR)\n\n    if not _is_writable_dir(configdir):\n        raise RuntimeError(f'Could not write to SUNPY_CONFIGDIR=\"{configdir}\"')\n    return configdir\n", "path": "sunpy/util/config.py"}]}