Created
September 4, 2020 01:20
-
-
Save skeeto/89af673a0a0d24de32ad19ee505c8dbd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Asynchronous file open/close | |
# https://nullprogram.com/blog/2020/09/04/ | |
import asyncio | |
class _AsyncOpen(): | |
def __init__(self, args, kwargs): | |
self._args = args | |
self._kwargs = kwargs | |
def __aenter__(self): | |
def thread_open(): | |
return open(*self._args, **self._kwargs) | |
loop = asyncio.get_event_loop() | |
self._future = loop.run_in_executor(None, thread_open) | |
return self._future | |
async def __aexit__(self, exc_type, exc, tb): | |
file = await self._future | |
def thread_close(): | |
file.close() | |
loop = asyncio.get_event_loop() | |
await loop.run_in_executor(None, thread_close) | |
def aopen(*args, **kwargs): | |
return _AsyncOpen(args, kwargs) | |
## Test / demo | |
async def heartbeat(): | |
while True: | |
await asyncio.sleep(0.5) | |
print('HEARTBEAT') | |
async def write(i): | |
async with aopen(f'/tmp/{i}', 'w') as out: | |
print(i, file=out) | |
async def main(): | |
beat = asyncio.create_task(heartbeat()) | |
tasks = [asyncio.create_task(write(i)) for i in range(5)] | |
await asyncio.gather(*tasks) | |
beat.cancel() | |
asyncio.run(main()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* $ cc -shared -fPIC -o open64.so open64.c */ | |
#define _GNU_SOURCE | |
#include <dlfcn.h> | |
#include <string.h> | |
#include <unistd.h> | |
int | |
open64(const char *path, int flags, int mode) | |
{ | |
if (!strncmp(path, "/tmp/", 5)) { | |
sleep(3); | |
} | |
int (*orig)(const char *, int, int) = dlsym(RTLD_NEXT, "open64"); | |
return orig(path, flags, mode); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment