1#!/usr/bin/env python3 2import string, sys, time 3try: 4 from _thread import get_ident 5except: 6 from thread import get_ident 7from threading import Thread, Lock 8 9import setup_test 10import libxml2 11 12# Memory debug specific 13libxml2.debugMemory(1) 14 15THREADS_COUNT = 15 16 17failed = 0 18 19class ErrorHandler: 20 21 def __init__(self): 22 self.errors = [] 23 self.lock = Lock() 24 25 def handler(self,ctx,str): 26 self.lock.acquire() 27 self.errors.append(str) 28 self.lock.release() 29 30def getLineNumbersDefault(): 31 old = libxml2.lineNumbersDefault(0) 32 libxml2.lineNumbersDefault(old) 33 return old 34 35def test(expectedLineNumbersDefault): 36 time.sleep(1) 37 global failed 38 # check a per thread-global 39 if expectedLineNumbersDefault != getLineNumbersDefault(): 40 failed = 1 41 print("FAILED to obtain correct value for " \ 42 "lineNumbersDefault in thread %d" % get_ident()) 43 # check the global error handler 44 # (which is NOT per-thread in the python bindings) 45 try: 46 doc = libxml2.parseFile("bad.xml") 47 except: 48 pass 49 else: 50 assert "failed" 51 52# global error handler 53eh = ErrorHandler() 54libxml2.registerErrorHandler(eh.handler,"") 55 56# set on the main thread only 57libxml2.lineNumbersDefault(1) 58test(1) 59ec = len(eh.errors) 60if ec == 0: 61 print("FAILED: should have obtained errors") 62 sys.exit(1) 63 64ts = [] 65for i in range(THREADS_COUNT): 66 # expect 0 for lineNumbersDefault because 67 # the new value has been set on the main thread only 68 ts.append(Thread(target=test,args=(0,))) 69for t in ts: 70 t.start() 71for t in ts: 72 t.join() 73 74if len(eh.errors) != ec+THREADS_COUNT*ec: 75 print("FAILED: did not obtain the correct number of errors") 76 sys.exit(1) 77 78# set lineNumbersDefault for future new threads 79libxml2.thrDefLineNumbersDefaultValue(1) 80ts = [] 81for i in range(THREADS_COUNT): 82 # expect 1 for lineNumbersDefault 83 ts.append(Thread(target=test,args=(1,))) 84for t in ts: 85 t.start() 86for t in ts: 87 t.join() 88 89if len(eh.errors) != ec+THREADS_COUNT*ec*2: 90 print("FAILED: did not obtain the correct number of errors") 91 sys.exit(1) 92 93if failed: 94 print("FAILED") 95 sys.exit(1) 96 97# Memory debug specific 98libxml2.cleanupParser() 99# Note that this can leak memory on Windows if the global state 100# destructors weren't run yet. They should be called eventually, 101# so this leak should be harmless. 102if libxml2.debugMemory(1) == 0: 103 print("OK") 104else: 105 print("Memory leak %d bytes" % (libxml2.debugMemory(1))) 106