Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not Thread Safe? #190

Open
ssokol opened this issue Jan 24, 2020 · 9 comments
Open

Not Thread Safe? #190

ssokol opened this issue Jan 24, 2020 · 9 comments

Comments

@ssokol
Copy link
Contributor

ssokol commented Jan 24, 2020

I have a rather complicated app that makes use of GEOSwift (currently 4.1.0 with geos 4.0.1) in several classes. I'm testing my app with Thread Sanitizer enabled and it seems that all is not thread safe at the geos layer. The sanitizer is finding concurrent access to the reference count in the GeometryFactory class.

The error below shows two threads in entirely different portions of my app: one handles placement of weather radar data, another handles airspace tracking. The only thing they have in common is that they both create polygons using GEOSwift.

Any suggestions?

==================
WARNING: ThreadSanitizer: data race (pid=42655)
  Write of size 4 at 0x7b0c0018b8d0 by thread T53:
    #0 geos::geom::GeometryFactory::addRef() const GeometryFactory.cpp:795 (geos:x86_64+0x19835f)
    #1 geos::geom::Geometry::Geometry(geos::geom::GeometryFactory const*) Geometry.cpp:119 (geos:x86_64+0x16b5c9)
    #2 geos::geom::LinearRing::LinearRing(geos::geom::CoordinateSequence*, geos::geom::GeometryFactory const*) LinearRing.cpp:43 (geos:x86_64+0x2510b5)
    #3 geos::geom::GeometryFactory::createLinearRing(geos::geom::CoordinateSequence*) const GeometryFactory.cpp:469 (geos:x86_64+0x19374f)
    #4 GEOSGeom_createLinearRing_r geos_ts_c.cpp:4454 (geos:x86_64+0x1e8d96)
    #5 $s8GEOSwift38GEOJSONCreatePolygonFromRepresentation33_A914A04461F29F4AF7F277F711199711LLyAA0C0CSgSo7NSArrayCFAA10LinearRingCSgSaySaySdGGXEfU_ GeoJSON.swift:340 (GEOSwift:x86_64+0xc07c)
    #6 $sSaySaySdGG8GEOSwift10LinearRingCSgs5Error_pIggozo_AbFsAG_pIegnrzo_TR <compiler-generated> (GEOSwift:x86_64+0xc31a)
    #7 $sSaySaySdGG8GEOSwift10LinearRingCSgs5Error_pIggozo_AbFsAG_pIegnrzo_TRTA <compiler-generated> (GEOSwift:x86_64+0xc422)
    #8 $sSTsE10compactMapySayqd__Gqd__Sg7ElementQzKXEKlF <null>:23590288 (libswiftCore.dylib:x86_64+0x1556d8)
    #9 $s8GEOSwift20ParseGEOJSONGeometry33_A914A04461F29F4AF7F277F711199711LL_18coordinatesNSArrayAA8GeometryCSgSS_So0L0CtF GeoJSON.swift:243 (GEOSwift:x86_64+0x914d)
    #10 $s8GEOSwift18ParseGEOJSONObject33_A914A04461F29F4AF7F277F711199711LLySayAA7FeatureCGSgSDySSyXlGF GeoJSON.swift:123 (GEOSwift:x86_64+0x486d)
    #11 $sSa8GEOSwiftAA7FeatureCRszlE21fromGeoJSONDictionaryySayACGSgSDySSyXlGFZ GeoJSON.swift:92 (GEOSwift:x86_64+0x319b)
    #12 $s8GEOSwift8GeometryC21fromGeoJSONDictionaryySayACGSgSDySSyXlGFZ GeoJSON.swift:24 (GEOSwift:x86_64+0x2ffc)
    #13 $s13FlightBox_PFD17FBAirspaceFactoryC31findAirspacesRelativeToLocation5pointSayAA0D0CGSo10CLLocationC_tF FBAirspace.swift:481 (FlightBox PFD:x86_64+0x100ccd453)
    #14 $s13FlightBox_PFD17FBAirspaceFactoryC23checkAirspacesAndNotify33_FEE8F2CABC0974AED7DFA8432B44A341LLyyF FBAirspace.swift:177 (FlightBox PFD:x86_64+0x100cbe4e2)
    #15 $s13FlightBox_PFD17FBAirspaceFactoryC14locationUpdate12notificationySo14NSNotificationC_tFyycfU_ FBAirspace.swift:161 (FlightBox PFD:x86_64+0x100cbd84d)
    #16 $s13FlightBox_PFD17FBAirspaceFactoryC14locationUpdate12notificationySo14NSNotificationC_tFyycfU_TA <compiler-generated> (FlightBox PFD:x86_64+0x100cbd89d)
    #17 $sIeg_IeyB_TR <compiler-generated> (FlightBox PFD:x86_64+0x100020230)
    #18 __tsan::invoke_and_release_block(void*) <null>:23590288 (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x6a89b)
    #19 _dispatch_client_callout <null>:23590288 (libdispatch.dylib:x86_64+0x2d47)

  Previous write of size 4 at 0x7b0c0018b8d0 by thread T38:
    #0 geos::geom::GeometryFactory::addRef() const GeometryFactory.cpp:795 (geos:x86_64+0x19835f)
    #1 geos::geom::Geometry::Geometry(geos::geom::GeometryFactory const*) Geometry.cpp:119 (geos:x86_64+0x16b5c9)
    #2 geos::geom::LinearRing::LinearRing(geos::geom::CoordinateSequence*, geos::geom::GeometryFactory const*) LinearRing.cpp:43 (geos:x86_64+0x2510b5)
    #3 geos::geom::GeometryFactory::createLinearRing(geos::geom::CoordinateSequence*) const GeometryFactory.cpp:469 (geos:x86_64+0x19374f)
    #4 geos::io::WKTReader::readLinearRingText(geos::io::StringTokenizer*) WKTReader.cpp:273 (geos:x86_64+0x4c9656)
    #5 geos::io::WKTReader::readPolygonText(geos::io::StringTokenizer*) WKTReader.cpp:380 (geos:x86_64+0x4c97c1)
    #6 geos::io::WKTReader::readGeometryTaggedText(geos::io::StringTokenizer*) WKTReader.cpp:235 (geos:x86_64+0x4c72d4)
    #7 geos::io::WKTReader::read(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) WKTReader.cpp:67 (geos:x86_64+0x4c6f74)
    #8 GEOSWKTReader_read_r geos_ts_c.cpp:5112 (geos:x86_64+0x1ecfcf)
    #9 $s8GEOSwift8GeometryC6createyACSgSSFZ GEOS.swift:154 (GEOSwift:x86_64+0x1ca26)
    #10 $s13FlightBox_PFD13FBNexradBlockC8overlaps3boxSbSo9GLMapBBoxV_tF FBNexradBlock.swift:161 (FlightBox PFD:x86_64+0x100bc232b)
    #11 $s13FlightBox_PFD17MFDViewControllerC16updateRadarLayer3nrbyAA13FBNexradBlockC_tF MFDViewController.swift:2388 (FlightBox PFD:x86_64+0x100e6c733)
    #12 $s13FlightBox_PFD14FBRadarFactoryC19handleRegionalBlock33_1A1A86C987D191B4610B1A75BB833973LL2nd4fisbyAA08FBNexradH0C_AA10FBFisbDataCtF FBNexrad.swift:175 (FlightBox PFD:x86_64+0x100c97d13)
    #13 $s13FlightBox_PFD14FBRadarFactoryC17processFisbReport33_1A1A86C987D191B4610B1A75BB833973LL4textySS_tF FBNexrad.swift:157 (FlightBox PFD:x86_64+0x100c9742a)
    #14 $s13FlightBox_PFD14FBRadarFactoryC26websocketDidReceiveMessage6socket4textyAA8FBSocketC_SStFyycfU_ FBNexrad.swift:83 (FlightBox PFD:x86_64+0x100c93662)
    #15 $s13FlightBox_PFD14FBRadarFactoryC26websocketDidReceiveMessage6socket4textyAA8FBSocketC_SStFyycfU_TA <compiler-generated> (FlightBox PFD:x86_64+0x100c9371f)
    #16 $sIeg_IeyB_TR <compiler-generated> (FlightBox PFD:x86_64+0x100020230)
    #17 +[ObjC catchException:error:] ObjC.m:7 (FlightBox PFD:x86_64+0x100002589)
    #18 $s13FlightBox_PFD14FBRadarFactoryC26websocketDidReceiveMessage6socket4textyAA8FBSocketC_SStF FBNexrad.swift:82 (FlightBox PFD:x86_64+0x100c931a7)
    #19 $s13FlightBox_PFD14FBRadarFactoryCAA19FBWebSocketDelegateA2aDP26websocketDidReceiveMessage6socket4textyAA8FBSocketC_SStFTW <compiler-generated> (FlightBox PFD:x86_64+0x100c9d5a8)
    #20 $s13FlightBox_PFD11FBTCPSocketC13handleMessage3msgySS_tFyycfU_ FBTCPSocket2.swift:376 (FlightBox PFD:x86_64+0x100a1f945)
    #21 $s13FlightBox_PFD11FBTCPSocketC13handleMessage3msgySS_tFyycfU_TA <compiler-generated> (FlightBox PFD:x86_64+0x100a1fc97)
    #22 $sIeg_IeyB_TR <compiler-generated> (FlightBox PFD:x86_64+0x100020230)
    #23 __tsan::invoke_and_release_block(void*) <null>:23590288 (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x6a89b)
    #24 _dispatch_client_callout <null>:23590288 (libdispatch.dylib:x86_64+0x2d47)

  Location is heap block of size 40 at 0x7b0c0018b8b0 allocated by main thread:
    #0 operator new(unsigned long) <null>:23590320 (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x6df2b)
    #1 geos::geom::GeometryFactory::getDefaultInstance() GeometryFactory.cpp:787 (geos:x86_64+0x198261)
    #2 GEOSContextHandle_HS::GEOSContextHandle_HS() geos_ts_c.cpp:180 (geos:x86_64+0x1fa951)
    #3 GEOSContextHandle_HS::GEOSContextHandle_HS() geos_ts_c.cpp:178 (geos:x86_64+0x1ceb98)
    #4 GEOS_init_r geos_ts_c.cpp:340 (geos:x86_64+0x1ce9a4)
    #5 $s8GEOSwift11GEOS_HANDLEs13OpaquePointerVvpfiADyXEfU_ GEOS.swift:19 (GEOSwift:x86_64+0x19bee)
    #6 globalinit_33_4564CA7B595C96361B01EBB682EC9AC6_func1 GEOS.swift:17 (GEOSwift:x86_64+0x19b75)
    #7 dispatch_once <null>:23590320 (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x6b114)
    #8 dispatch_once_f <null>:23590320 (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x6b200)
    #9 swift_once <null>:23590320 (libswiftCore.dylib:x86_64+0x2f7668)
    #10 $s8GEOSwift38GEOJSONSequenceFromArrayRepresentation33_A914A04461F29F4AF7F277F711199711LLys13OpaquePointerVSgSaySaySdGGF GeoJSON.swift:298 (GEOSwift:x86_64+0x9880)
    #11 $s8GEOSwift38GEOJSONCreatePolygonFromRepresentation33_A914A04461F29F4AF7F277F711199711LLyAA0C0CSgSo7NSArrayCFAA10LinearRingCSgSaySaySdGGXEfU_ GeoJSON.swift:339 (GEOSwift:x86_64+0xbfbe)
    #12 $sSaySaySdGG8GEOSwift10LinearRingCSgs5Error_pIggozo_AbFsAG_pIegnrzo_TR <compiler-generated> (GEOSwift:x86_64+0xc31a)
    #13 $sSaySaySdGG8GEOSwift10LinearRingCSgs5Error_pIggozo_AbFsAG_pIegnrzo_TRTA <compiler-generated> (GEOSwift:x86_64+0xc422)
    #14 $sSTsE10compactMapySayqd__Gqd__Sg7ElementQzKXEKlF <null>:23590320 (libswiftCore.dylib:x86_64+0x1556d8)
    #15 $s8GEOSwift20ParseGEOJSONGeometry33_A914A04461F29F4AF7F277F711199711LL_18coordinatesNSArrayAA8GeometryCSgSS_So0L0CtF GeoJSON.swift:236 (GEOSwift:x86_64+0x8eda)
    #16 $s8GEOSwift18ParseGEOJSONObject33_A914A04461F29F4AF7F277F711199711LLySayAA7FeatureCGSgSDySSyXlGF GeoJSON.swift:123 (GEOSwift:x86_64+0x486d)
    #17 $sSa8GEOSwiftAA7FeatureCRszlE21fromGeoJSONDictionaryySayACGSgSDySSyXlGFZ GeoJSON.swift:92 (GEOSwift:x86_64+0x319b)
    #18 $s8GEOSwift8GeometryC21fromGeoJSONDictionaryySayACGSgSDySSyXlGFZ GeoJSON.swift:24 (GEOSwift:x86_64+0x2ffc)
    #19 $s13FlightBox_PFD17FBAirspaceFactoryC19loadAirspaceObjects3map10completionySo9GLMapViewC_ySbctF FBAirspace.swift:323 (FlightBox PFD:x86_64+0x100cc6d4d)
    #20 $s13FlightBox_PFD17FBAirspaceFactoryC11registerMap3mapySo9GLMapViewC_tF FBAirspace.swift:221 (FlightBox PFD:x86_64+0x100cbfd4b)
    #21 $s13FlightBox_PFD17MFDViewControllerC21initAirspaceFunctionsyyF MFDViewController.swift:143 (FlightBox PFD:x86_64+0x100e1ca67)
    #22 $s13FlightBox_PFD15FBSystemManagerC16initMapAirspaces33_991110EC59964F05A353B90D767726C9LLyyF FBSystemManager.swift:105 (FlightBox PFD:x86_64+0x10010e896)
    #23 $sTA.159 <compiler-generated> (FlightBox PFD:x86_64+0x10011d9b4)
    #24 $sIeg_IeyB_TR <compiler-generated> (FlightBox PFD:x86_64+0x100020230)
    #25 __tsan::invoke_and_release_block(void*) <null>:23590320 (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x6a89b)
    #26 _dispatch_client_callout <null>:23590320 (libdispatch.dylib:x86_64+0x2d47)
    #27 start <null>:23590320 (libdyld.dylib:x86_64+0xc24)

  Thread T53 (tid=2745722, running) is a GCD worker thread

  Thread T38 (tid=2745598, running) is a GCD worker thread

SUMMARY: ThreadSanitizer: data race GeometryFactory.cpp:795 in geos::geom::GeometryFactory::addRef() const
==================
@ssokol
Copy link
Contributor Author

ssokol commented Jan 24, 2020

Looks like thread safety is a feature of v5 and later, so I'll try moving to that.

@ssokol ssokol closed this as completed Jan 24, 2020
@ssokol
Copy link
Contributor Author

ssokol commented Sep 26, 2020

I'm running the latest / greatest (geos (5.0.0), GEOSwift (7.1.0)) and still seeing data race issues like:

==================
WARNING: ThreadSanitizer: data race (pid=93529)
  Write of size 1 at 0x000108d04a00 by thread T38:
    #0 geos::util::Interrupt::cancel() Interrupt.cpp:43 (geos:x86_64+0x2b5718)
    #1 GEOS_init_r geos_ts_c.cpp:352 (geos:x86_64+0x2521c6)
    #2 GEOSContext.init() GEOSContext.swift:8 (GEOSwift:x86_64+0x34a1c)
    #3 GEOSContext.__allocating_init() GEOSContext.swift (GEOSwift:x86_64+0x34899)
    #4 WKTInitializableInternal.init(wkt:) WKTInitializable.swift:12 (GEOSwift:x86_64+0x5bf2a)
    #5 FBNexradBlock.overlaps(box:) FBNexradBlock.swift:171 (FlightBox PFD:x86_64+0x1008a7460)
    #6 MFDViewController.updateRadarLayer(nrb:) MFDViewController.swift:2480 (FlightBox PFD:x86_64+0x100bacc27)
    #7 FBRadarFactory.handleRegionalBlock(nd:fisb:) FBNexrad.swift:180 (FlightBox PFD:x86_64+0x10099b6c0)
    #8 FBRadarFactory.processFisbReport(text:) FBNexrad.swift:163 (FlightBox PFD:x86_64+0x10099ad94)
    #9 closure #1 in FBRadarFactory.websocketDidReceiveMessage(socket:text:) FBNexrad.swift:89 (FlightBox PFD:x86_64+0x100997542)
    #10 partial apply for closure #1 in FBRadarFactory.websocketDidReceiveMessage(socket:text:) <compiler-generated> (FlightBox PFD:x86_64+0x1009975f9)
    #11 thunk for @escaping @callee_guaranteed () -> () <compiler-generated> (FlightBox PFD:x86_64+0x100020833)
    #12 +[ObjC catchException:error:] ObjC.m:7 (FlightBox PFD:x86_64+0x100003e66)
    #13 FBRadarFactory.websocketDidReceiveMessage(socket:text:) FBNexrad.swift:88 (FlightBox PFD:x86_64+0x100996f9f)
    #14 closure #1 in FBRadarFactory.handleNexradUpdate(socket:text:) FBNexrad.swift:76 (FlightBox PFD:x86_64+0x100996a51)
    #15 partial apply for closure #1 in FBRadarFactory.handleNexradUpdate(socket:text:) <compiler-generated> (FlightBox PFD:x86_64+0x100996b2d)
    #16 thunk for @escaping @callee_guaranteed () -> () <compiler-generated> (FlightBox PFD:x86_64+0x100020833)
    #17 __tsan::invoke_and_release_block(void*) <null>:2 (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x70f1b)
    #18 _dispatch_client_callout <null>:2 (libdispatch.dylib:x86_64+0x3a87)

  Previous write of size 1 at 0x000108d04a00 by thread T41:
    #0 geos::util::Interrupt::cancel() Interrupt.cpp:43 (geos:x86_64+0x2b5718)
    #1 GEOS_init_r geos_ts_c.cpp:352 (geos:x86_64+0x2521c6)
    #2 GEOSContext.init() GEOSContext.swift:8 (GEOSwift:x86_64+0x34a1c)
    #3 GEOSContext.__allocating_init() GEOSContext.swift (GEOSwift:x86_64+0x34899)
    #4 GeometryConvertible.evaluateBinaryPredicate(_:with:) GeometryConvertible+GEOS.swift:88 (GEOSwift:x86_64+0x29439)
    #5 GeometryConvertible.contains(_:) GeometryConvertible+GEOS.swift:124 (GEOSwift:x86_64+0x2afd2)
    #6 FBAirspaceFactory.findAirspacesRelativeToLocation(point:) FBAirspace.swift:507 (FlightBox PFD:x86_64+0x1009e3217)
    #7 FBAirspaceFactory.checkAirspacesAndNotify() FBAirspace.swift:177 (FlightBox PFD:x86_64+0x1009d357b)
    #8 closure #1 in FBAirspaceFactory.locationUpdate(notification:) FBAirspace.swift:161 (FlightBox PFD:x86_64+0x1009d271d)
    #9 partial apply for closure #1 in FBAirspaceFactory.locationUpdate(notification:) <compiler-generated> (FlightBox PFD:x86_64+0x1009d276d)
    #10 thunk for @escaping @callee_guaranteed () -> () <compiler-generated> (FlightBox PFD:x86_64+0x100020833)
    #11 __tsan::invoke_and_release_block(void*) <null>:2 (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x70f1b)
    #12 _dispatch_client_callout <null>:2 (libdispatch.dylib:x86_64+0x3a87)

  Location is global '(anonymous namespace)::requested' at 0x000108d04a00 (geos+0x000000664a00)

  Thread T38 (tid=7031926, running) is a GCD worker thread

  Thread T41 (tid=7032015, running) is a GCD worker thread

SUMMARY: ThreadSanitizer: data race Interrupt.cpp:43 in geos::util::Interrupt::cancel()
==================
ThreadSanitizer report breakpoint hit. Use 'thread info -s' to get extended information about the report.
==================
WARNING: ThreadSanitizer: data race (pid=93529)
  Write of size 4 at 0x000108d048f0 by thread T38:
    #0 geos::geom::GeometryFactory::addRef() const GeometryFactory.cpp:775 (geos:x86_64+0x212322)
    #1 geos::geom::Geometry::Geometry(geos::geom::GeometryFactory const*) Geometry.cpp:119 (geos:x86_64+0x1d9de3)
    #2 geos::geom::LineString::LineString(std::__1::unique_ptr<geos::geom::CoordinateSequence, std::__1::default_delete<geos::geom::CoordinateSequence> >&&, geos::geom::GeometryFactory const&) LineString.cpp:102 (geos:x86_64+0x335af9)
    #3 geos::geom::LinearRing::LinearRing(std::__1::unique_ptr<geos::geom::CoordinateSequence, std::__1::default_delete<geos::geom::CoordinateSequence> >&&, geos::geom::GeometryFactory const&) LinearRing.cpp:49 (geos:x86_64+0x2efc78)
    #4 geos::geom::LinearRing::LinearRing(std::__1::unique_ptr<geos::geom::CoordinateSequence, std::__1::default_delete<geos::geom::CoordinateSequence> >&&, geos::geom::GeometryFactory const&) LinearRing.cpp:50 (geos:x86_64+0x2efd98)
    #5 geos::geom::GeometryFactory::createLinearRing(std::__1::unique_ptr<geos::geom::CoordinateSequence, std::__1::default_delete<geos::geom::CoordinateSequence> >&&) const GeometryFactory.cpp:479 (geos:x86_64+0x20d45d)
    #6 geos::io::WKTReader::readLinearRingText(geos::io::StringTokenizer*) WKTReader.cpp:276 (geos:x86_64+0x5d9110)
    #7 geos::io::WKTReader::readPolygonText(geos::io::StringTokenizer*) WKTReader.cpp:359 (geos:x86_64+0x5d930c)
    #8 geos::io::WKTReader::readGeometryTaggedText(geos::io::StringTokenizer*) WKTReader.cpp:232 (geos:x86_64+0x5d6cd1)
    #9 geos::io::WKTReader::read(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) WKTReader.cpp:67 (geos:x86_64+0x5d6a69)
    #10 GEOSWKTReader_read_r geos_ts_c.cpp:4872 (geos:x86_64+0x273193)
    #11 closure #1 in WKTReader.read(_:) WKTInitializable.swift:46 (GEOSwift:x86_64+0x5d361)
    #12 partial apply for closure #1 in WKTReader.read(_:) <compiler-generated> (GEOSwift:x86_64+0x5d3b8)
    #13 thunk for @callee_guaranteed (@unowned UnsafePointer<Int8>) -> (@unowned OpaquePointer?, @error @owned Error) <compiler-generated> (GEOSwift:x86_64+0x5d42e)
    #14 partial apply for thunk for @callee_guaranteed (@unowned UnsafePointer<Int8>) -> (@unowned OpaquePointer?, @error @owned Error) <compiler-generated> (GEOSwift:x86_64+0x5d512)
    #15 _StringGuts._slowWithCString<A>(_:) <null>:2 (libswiftCore.dylib:x86_64+0x1b476e)
    #16 WKTInitializableInternal.init(wkt:) WKTInitializable.swift:14 (GEOSwift:x86_64+0x5c04e)
    #17 FBNexradBlock.overlaps(box:) FBNexradBlock.swift:171 (FlightBox PFD:x86_64+0x1008a7460)
    #18 MFDViewController.updateRadarLayer(nrb:) MFDViewController.swift:2480 (FlightBox PFD:x86_64+0x100bacc27)
    #19 FBRadarFactory.handleRegionalBlock(nd:fisb:) FBNexrad.swift:180 (FlightBox PFD:x86_64+0x10099b6c0)
    #20 FBRadarFactory.processFisbReport(text:) FBNexrad.swift:163 (FlightBox PFD:x86_64+0x10099ad94)
    #21 closure #1 in FBRadarFactory.websocketDidReceiveMessage(socket:text:) FBNexrad.swift:89 (FlightBox PFD:x86_64+0x100997542)
    #22 partial apply for closure #1 in FBRadarFactory.websocketDidReceiveMessage(socket:text:) <compiler-generated> (FlightBox PFD:x86_64+0x1009975f9)
    #23 thunk for @escaping @callee_guaranteed () -> () <compiler-generated> (FlightBox PFD:x86_64+0x100020833)
    #24 +[ObjC catchException:error:] ObjC.m:7 (FlightBox PFD:x86_64+0x100003e66)
    #25 FBRadarFactory.websocketDidReceiveMessage(socket:text:) FBNexrad.swift:88 (FlightBox PFD:x86_64+0x100996f9f)
    #26 closure #1 in FBRadarFactory.handleNexradUpdate(socket:text:) FBNexrad.swift:76 (FlightBox PFD:x86_64+0x100996a51)
    #27 partial apply for closure #1 in FBRadarFactory.handleNexradUpdate(socket:text:) <compiler-generated> (FlightBox PFD:x86_64+0x100996b2d)
    #28 thunk for @escaping @callee_guaranteed () -> () <compiler-generated> (FlightBox PFD:x86_64+0x100020833)
    #29 __tsan::invoke_and_release_block(void*) <null>:2 (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x70f1b)
    #30 _dispatch_client_callout <null>:2 (libdispatch.dylib:x86_64+0x3a87)

  Previous write of size 4 at 0x000108d048f0 by thread T41:
    #0 geos::geom::GeometryFactory::addRef() const GeometryFactory.cpp:775 (geos:x86_64+0x212322)
    #1 geos::geom::Geometry::Geometry(geos::geom::GeometryFactory const*) Geometry.cpp:119 (geos:x86_64+0x1d9de3)
    #2 geos::geom::LineString::LineString(geos::geom::CoordinateSequence*, geos::geom::GeometryFactory const*) LineString.cpp:92 (geos:x86_64+0x335919)
    #3 geos::geom::LineString::LineString(geos::geom::CoordinateSequence*, geos::geom::GeometryFactory const*) LineString.cpp:94 (geos:x86_64+0x335a68)
    #4 geos::geom::GeometryFactory::createLineString(geos::geom::CoordinateSequence*) const GeometryFactory.cpp:626 (geos:x86_64+0x21092f)
    #5 GEOSGeom_createLineString_r geos_ts_c.cpp:4356 (geos:x86_64+0x26f466)
    #6 closure #1 in LineString.geosObject(with:) LineString+GEOS.swift:15 (GEOSwift:x86_64+0x4587c)
    #7 makeGEOSObject(with:points:factory:) GEOSHelpers.swift:56 (GEOSwift:x86_64+0x39bb5)
    #8 LineString.geosObject(with:) LineString+GEOS.swift:14 (GEOSwift:x86_64+0x4572c)
    #9 Geometry.geosObject(with:) Geometry+GEOS.swift:33 (GEOSwift:x86_64+0x1f2bc)
    #10 GeometryConvertible.evaluateBinaryPredicate(_:with:) GeometryConvertible+GEOS.swift:89 (GEOSwift:x86_64+0x295b5)
    #11 GeometryConvertible.intersects(_:) GeometryConvertible+GEOS.swift:112 (GEOSwift:x86_64+0x2a8e2)
    #12 FBAirspaceFactory.findAirspacesOverlappingPath(point1:point2:) FBAirspace.swift:459 (FlightBox PFD:x86_64+0x1009e0b7c)
    #13 FBAirspaceFactory.checkAirspacesAndNotify() FBAirspace.swift:194 (FlightBox PFD:x86_64+0x1009d3ab8)
    #14 closure #1 in FBAirspaceFactory.locationUpdate(notification:) FBAirspace.swift:161 (FlightBox PFD:x86_64+0x1009d271d)
    #15 partial apply for closure #1 in FBAirspaceFactory.locationUpdate(notification:) <compiler-generated> (FlightBox PFD:x86_64+0x1009d276d)
    #16 thunk for @escaping @callee_guaranteed () -> () <compiler-generated> (FlightBox PFD:x86_64+0x100020833)
    #17 __tsan::invoke_and_release_block(void*) <null>:2 (libclang_rt.tsan_iossim_dynamic.dylib:x86_64+0x70f1b)
    #18 _dispatch_client_callout <null>:2 (libdispatch.dylib:x86_64+0x3a87)

  Location is global 'geos::geom::GeometryFactory::getDefaultInstance()::defInstance' at 0x000108d048c8 (geos+0x0000006648f0)

  Thread T38 (tid=7031926, running) is a GCD worker thread

  Thread T41 (tid=7032015, running) is a GCD worker thread

SUMMARY: ThreadSanitizer: data race GeometryFactory.cpp:775 in geos::geom::GeometryFactory::addRef() const

Anyone know how to resolve this?

@ssokol ssokol reopened this Sep 26, 2020
@macdrevx
Copy link
Member

Looks like this is the same issue we saw in #192

@ssokol
Copy link
Contributor Author

ssokol commented Sep 26, 2020

Ah, that's the one I should have updated. Apologies for that.

@macdrevx
Copy link
Member

No problem. At any rate, the issue is in the underlying geos C/C++ library (https://trac.osgeo.org/geos/ticket/1012), so you'd need to submit a patch there to see it fixed. Keep in mind that since GEOSwift (as of this writing) never uses the interrupt mechanism, the value that is being written by multiple threads is never read, so it shouldn't create any problems for your application.

If you're able to get a patch merged into a geos release, we can definitely update GEOSwift to use the new version.

I can imagine these warnings are a nuisance to you. If you just want to ignore specific ones, it looks like there is a way to do so:

@ssokol
Copy link
Contributor Author

ssokol commented Sep 28, 2020

Thank you. Just to double check: does the second warning about simultaneous writes to addRef() also have no practical impact on the application? I'm happy to ignore these if that's the case.

@macdrevx
Copy link
Member

Ah, I missed that there was a second one. Thanks for double checking.

So far, from what I can tell, it seems like every geos context uses a shared GeometryFactory that has a _refCount ivar to which access is not synchronized. That seems like a pretty big problem. I'll open a ticket on the project.

@macdrevx
Copy link
Member

Opened. https://trac.osgeo.org/geos/ticket/1052

Based on my reading of the geos source, I don't think this is going to create any actual problems, but I'd feel better if it weren't happening at all.

@ssokol
Copy link
Contributor Author

ssokol commented Sep 29, 2020

Thanks! Please let me know if anyone needs additional information from me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants