0001    //
0002    //  Dispatch.swift
0003    //  NSLinux
0004    //
0005    //  Created by John Holdsworth on 11/06/2015.
0006    //  Copyright (c) 2015 John Holdsworth. All rights reserved.
0007    //
0008    //  $Id: //depot/NSLinux/Sources/Dispatch.swift#9 $
0009    //
0010    //  Repo: https://github.com/johnno1962/NSLinux
0011    //
0012    
0013    // Hastily put together libdispatch substitutes
0014    
0015    #if os(Linux)
0016    import Glibc
0017    
0018    public typealias dispatch_queue_t = Int
0019    public typealias dispatch_time_t = Int64 // is UInt64 in Foundation/Dispatch
0020    public typealias dispatch_block_t = () -> ()
0021    public typealias dispatch_queue_attr_t = Int
0022     
0023    public let DISPATCH_QUEUE_CONCURRENT = 0, DISPATCH_QUEUE_PRIORITY_HIGH = 0, DISPATCH_QUEUE_PRIORITY_LOW = 0, DISPATCH_QUEUE_PRIORITY_BACKGROUND = 0
0024    
0025    public func dispatch_get_global_queue( type: Int, _ flags: UInt ) -> dispatch_queue_t {
0026        return type
0027    }
0028    
0029    public func dispatch_queue_create( name: UnsafePointer<Int8>, _ type: dispatch_queue_attr_t? ) -> dispatch_queue_t {
0030        return type ?? 0
0031    }
0032    
0033    public func dispatch_sync( queue: dispatch_queue_t, _ block: dispatch_block_t ) {
0034        block()
0035    }
0036    
0037    private class pthreadBlock {
0038    
0039        let block: dispatch_block_t
0040    
0041        init( block: dispatch_block_t ) {
0042            self.block = block
0043        }
0044    }
0045    
0046    private func pthreadRunner( arg: UnsafeMutablePointer<Void> ) -> UnsafeMutablePointer<Void> {
0047        let unmanaged = Unmanaged<pthreadBlock>.fromOpaque( COpaquePointer( arg ) )
0048        unmanaged.takeUnretainedValue().block()
0049        unmanaged.release()
0050        return arg
0051    }
0052    
0053    public func dispatch_async( queue: dispatch_queue_t, _ block: dispatch_block_t ) {
0054        let holder = Unmanaged.passRetained( pthreadBlock( block: block ) )
0055        let pointer = UnsafeMutablePointer<Void>( holder.toOpaque() )
0056        #if os(Linux)
0057        var pthread: pthread_t = 0
0058        #else
0059        var pthread: pthread_t = nil
0060        #endif
0061        if pthread_create( &pthread, nil, pthreadRunner, pointer ) == 0 {
0062            pthread_detach( pthread )
0063        }
0064        else {
0065            print( "pthread_create() error" )
0066        }
0067    }
0068    
0069    public let DISPATCH_TIME_NOW: dispatch_time_t = 0, NSEC_PER_SEC = 1_000_000_000
0070    
0071    public func dispatch_time( now: dispatch_time_t, _ nsec: Int64 ) -> dispatch_time_t {
0072        return nsec
0073    }
0074    
0075    public func dispatch_after( delay: dispatch_time_t, _ queue: dispatch_queue_t, _ block: dispatch_block_t ) {
0076        dispatch_async( queue, {
0077            sleep( UInt32(Int(delay)/NSEC_PER_SEC) )
0078            block()
0079        } )
0080    }
0081    
0082    #endif
0083