mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 21:51:50 +00:00 
			
		
		
		
	Issue #18756: os.urandom() now uses a lazily-opened persistent file descriptor, so as to avoid using many file descriptors when run in parallel from multiple threads.
This commit is contained in:
		
							parent
							
								
									267964c837
								
							
						
					
					
						commit
						4879a963d4
					
				
					 4 changed files with 48 additions and 13 deletions
				
			
		|  | @ -90,6 +90,7 @@ vms_urandom(unsigned char *buffer, Py_ssize_t size, int raise) | |||
| 
 | ||||
| 
 | ||||
| #if !defined(MS_WINDOWS) && !defined(__VMS) | ||||
| static int urandom_fd = -1; | ||||
| 
 | ||||
| /* Read size bytes from /dev/urandom into buffer.
 | ||||
|    Call Py_FatalError() on error. */ | ||||
|  | @ -133,18 +134,30 @@ dev_urandom_python(char *buffer, Py_ssize_t size) | |||
|     if (size <= 0) | ||||
|         return 0; | ||||
| 
 | ||||
|     Py_BEGIN_ALLOW_THREADS | ||||
|     fd = _Py_open("/dev/urandom", O_RDONLY); | ||||
|     Py_END_ALLOW_THREADS | ||||
|     if (fd < 0) | ||||
|     { | ||||
|         if (errno == ENOENT || errno == ENXIO || | ||||
|             errno == ENODEV || errno == EACCES) | ||||
|             PyErr_SetString(PyExc_NotImplementedError, | ||||
|                             "/dev/urandom (or equivalent) not found"); | ||||
|     if (urandom_fd >= 0) | ||||
|         fd = urandom_fd; | ||||
|     else { | ||||
|         Py_BEGIN_ALLOW_THREADS | ||||
|         fd = _Py_open("/dev/urandom", O_RDONLY); | ||||
|         Py_END_ALLOW_THREADS | ||||
|         if (fd < 0) | ||||
|         { | ||||
|             if (errno == ENOENT || errno == ENXIO || | ||||
|                 errno == ENODEV || errno == EACCES) | ||||
|                 PyErr_SetString(PyExc_NotImplementedError, | ||||
|                                 "/dev/urandom (or equivalent) not found"); | ||||
|             else | ||||
|                 PyErr_SetFromErrno(PyExc_OSError); | ||||
|             return -1; | ||||
|         } | ||||
|         if (urandom_fd >= 0) { | ||||
|             /* urandom_fd was initialized by another thread while we were
 | ||||
|                not holding the GIL, keep it. */ | ||||
|             close(fd); | ||||
|             fd = urandom_fd; | ||||
|         } | ||||
|         else | ||||
|             PyErr_SetFromErrno(PyExc_OSError); | ||||
|         return -1; | ||||
|             urandom_fd = fd; | ||||
|     } | ||||
| 
 | ||||
|     Py_BEGIN_ALLOW_THREADS | ||||
|  | @ -168,12 +181,20 @@ dev_urandom_python(char *buffer, Py_ssize_t size) | |||
|             PyErr_Format(PyExc_RuntimeError, | ||||
|                          "Failed to read %zi bytes from /dev/urandom", | ||||
|                          size); | ||||
|         close(fd); | ||||
|         return -1; | ||||
|     } | ||||
|     close(fd); | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| dev_urandom_close(void) | ||||
| { | ||||
|     if (urandom_fd >= 0) { | ||||
|         close(urandom_fd); | ||||
|         urandom_fd = -1; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #endif /* !defined(MS_WINDOWS) && !defined(__VMS) */ | ||||
| 
 | ||||
| /* Fill buffer with pseudo-random bytes generated by a linear congruent
 | ||||
|  | @ -271,3 +292,11 @@ _PyRandom_Init(void) | |||
| #endif | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| void | ||||
| _PyRandom_Fini(void) | ||||
| { | ||||
| #if !defined(MS_WINDOWS) && !defined(__VMS) | ||||
|     dev_urandom_close(); | ||||
| #endif | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Antoine Pitrou
						Antoine Pitrou