def acquire_read(self, timeout=None):
if timeout is not None:<EOL><INDENT>endtime = time() + timeout<EOL><DEDENT>me = currentThread()<EOL>self.__condition.acquire()<EOL>try:<EOL><INDENT>if self.__writer is me:<EOL><INDENT>self.__writercount += <NUM_LIT:1><EOL>return<EOL><DEDENT>while True:<EOL><INDENT>if self.__writer is None:<EOL><INDENT>if self.__upgradewritercount or self.__pendingwriters:<EOL><INDENT>if me in self.__readers:<EOL><INDENT>self.__readers[me] += <NUM_LIT:1><EOL>return<EOL><DEDENT><DEDENT>else:<EOL><INDENT>self.__readers[me] = self.__readers.get(me, <NUM_LIT:0>) + <NUM_LIT:1><EOL>return<EOL><DEDENT><DEDENT>if timeout is not None:<EOL><INDENT>remaining = endtime - time()<EOL>if remaining <= <NUM_LIT:0>:<EOL><INDENT>raise RuntimeError("<STR_LIT>")<EOL><DEDENT>self.__condition.wait(remaining)<EOL><DEDENT>else:<EOL><INDENT>self.__condition.wait()<EOL><DEDENT><DEDENT><DEDENT>finally:<EOL><INDENT>self.__condition.release()<EOL><DEDENT>
Acquire a read lock for the current thread, waiting at most
        timeout seconds or doing a non-blocking check in case timeout is <= 0.

        In case timeout is None, the call to acquire_read blocks until the
        lock request can be serviced.

        In case the timeout expires before the lock could be serviced, a
        RuntimeError is thrown.