text:
{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveGeneric #-}

-----------------------------------------------------------------------------
-- |
-- Module      :  Distribution.Simple.Program.Db
-- Copyright   :  Isaac Jones 2006, Duncan Coutts 2007-2009
--
-- Maintainer  :  cabal-devel@haskell.org
-- Portability :  portable
--
-- This provides a 'ProgramDb' type which holds configured and not-yet
-- configured programs. It is the parameter to lots of actions elsewhere in
-- Cabal that need to look up and run programs. If we had a Cabal monad,
-- the 'ProgramDb' would probably be a reader or state component of it.
--
-- One nice thing about using it is that any program that is
-- registered with Cabal will get some \"configure\" and \".cabal\"
-- helpers like --with-foo-args --foo-path= and extra-foo-args.
--
-- There's also a hook for adding programs in a Setup.lhs script.  See
-- hookedPrograms in 'Distribution.Simple.UserHooks'.  This gives a
-- hook user the ability to get the above flags and such so that they
-- don't have to write all the PATH logic inside Setup.lhs.

module Distribution.Simple.Program.Db (
    -- * The collection of configured programs we can run
    ProgramDb,
    emptyProgramDb,
    defaultProgramDb,
    restoreProgramDb,

    -- ** Query and manipulate the program db
    addKnownProgram,
    addKnownPrograms,
    lookupKnownProgram,
    knownPrograms,
    getProgramSearchPath,
    setProgramSearchPath,
    modifyProgramSearchPath,
    userSpecifyPath,
    userSpecifyPaths,
    userMaybeSpecifyPath,
    userSpecifyArgs,
    userSpecifyArgss,
    userSpecifiedArgs,
    lookupProgram,
    updateProgram,
    configuredPrograms,

    -- ** Query and manipulate the program db
    configureProgram,
    configureAllKnownPrograms,
    lookupProgramVersion,
    reconfigurePrograms,
    requireProgram,
    requireProgramVersion,

  ) where

import Distribution.Simple.Program.Types
         ( Program(..), ProgArg, ConfiguredProgram(..), ProgramLocation(..) )
import Distribution.Simple.Program.Find
         ( ProgramSearchPath, defaultProgramSearchPath
         , findProgramOnSearchPath, programSearchPathAsPATHVar )
import Distribution.Simple.Program.Builtin
         ( builtinPrograms )
import Distribution.Simple.Utils
         ( die, doesExecutableExist )
import Distribution.Version
         ( Version, VersionRange, isAnyVersion, withinRange )
import Distribution.Text
         ( display )
import Distribution.Verbosity
         ( Verbosity )

import Distribution.Compat.Binary (Binary(..))
#if __GLASGOW_HASKELL__ < 710
import Data.Functor ((<$>))
#endif
import Data.List
         ( foldl' )
import Data.Maybe
         ( catMaybes )
import qualified Data.Map as Map
import Control.Monad
         ( join, foldM )

-- ------------------------------------------------------------
-- * Programs database
-- ------------------------------------------------------------

-- | The configuration is a collection of information about programs. It
-- contains information both about configured programs and also about programs
-- that we are yet to configure.
--
-- The idea is that we start from a collection of unconfigured programs and one
-- by one we try to configure them at which point we move them into the
-- configured collection. For unconfigured programs we record not just the
-- 'Program' but also any user-provided arguments and location for the program.
data ProgramDb = ProgramDb {
        unconfiguredProgs :: UnconfiguredProgs,
        progSearchPath    :: ProgramSearchPath,
        configuredProgs   :: ConfiguredProgs
    }

type UnconfiguredProgram = (Program, Maybe FilePath, [ProgArg])
type UnconfiguredProgs   = Map.Map String UnconfiguredProgram
type ConfiguredProgs     = Map.Map String ConfiguredProgram

emptyProgramDb :: ProgramDb
emptyProgramDb = ProgramDb Map.empty defaultProgramSearchPath Map.empty

defaultProgramDb :: ProgramDb
defaultProgramDb = restoreProgramDb builtinPrograms emptyProgramDb

-- internal helpers:
updateUnconfiguredProgs :: (UnconfiguredProgs -> UnconfiguredProgs)
                        -> ProgramDb -> ProgramDb
updateUnconfiguredProgs update conf =
  conf { unconfiguredProgs = update (unconfiguredProgs conf) }

updateConfiguredProgs :: (ConfiguredProgs -> ConfiguredProgs)
                      -> ProgramDb -> ProgramDb
updateConfiguredProgs update conf =
  conf { configuredProgs = update (configuredProgs conf) }

-- Read & Show instances are based on listToFM
-- Note that we only serialise the configured part of the database, this is
-- because we don't need the unconfigured part after the configure stage, and
-- additionally because we cannot read/show 'Program' as it contains functions.
instance Show ProgramDb where
  show = show . Map.toAscList . configuredProgs

instance Read ProgramDb where
  readsPrec p s =
    [ (emptyProgramDb { configuredProgs = Map.fromList s' }, r)
    | (s', r) <- readsPrec p s ]

instance Binary ProgramDb where
  put = put . configuredProgs
  get = do
      progs <- get
      return $! emptyProgramDb { configuredProgs = progs }

-- | The Read\/Show instance does not preserve all the unconfigured 'Programs'
-- because 'Program' is not in Read\/Show because it contains functions. So to
-- fully restore a deserialised 'ProgramDb' use this function to add
-- back all the known 'Program's.
--
-- * It does not add the default programs, but you probably want them, use
--   'builtinPrograms' in addition to any extra you might need.
--
restoreProgramDb :: [Program] -> ProgramDb -> ProgramDb
restoreProgramDb = addKnownPrograms

-- -------------------------------
-- Managing unconfigured programs

-- | Add a known program that we may configure later
--
addKnownProgram :: Program -> ProgramDb -> ProgramDb
addKnownProgram prog = updateUnconfiguredProgs $
  Map.insertWith combine (programName prog) (prog, Nothing, [])
  where combine _ (_, path, args) = (prog, path, args)

addKnownPrograms :: [Program] -> ProgramDb -> ProgramDb
addKnownPrograms progs conf = foldl' (flip addKnownProgram) conf progs

lookupKnownProgram :: String -> ProgramDb -> Maybe Program
lookupKnownProgram name =
  fmap (\(p,_,_)->p) . Map.lookup name . unconfiguredProgs

knownPrograms :: ProgramDb -> [(Program, Maybe ConfiguredProgram)]
knownPrograms conf =
  [ (p,p') | (p,_,_) <- Map.elems (unconfiguredProgs conf)
           , let p' = Map.lookup (programName p) (configuredProgs conf) ]

-- | Get the current 'ProgramSearchPath' used by the 'ProgramDb'.
-- This is the default list of locations where programs are looked for when
-- configuring them. This can be overridden for specific programs (with
-- 'userSpecifyPath'), and specific known programs can modify or ignore this
-- search path in their own configuration code.
--
getProgramSearchPath :: ProgramDb -> ProgramSearchPath
getProgramSearchPath = progSearchPath

-- | Change the current 'ProgramSearchPath' used by the 'ProgramDb'.
-- This will affect programs that are configured from here on, so you
-- should usually set it before configuring any programs.
--
setProgramSearchPath :: ProgramSearchPath -> ProgramDb -> ProgramDb
setProgramSearchPath searchpath db = db { progSearchPath = searchpath }

-- | Modify the current 'ProgramSearchPath' used by the 'ProgramDb'.
-- This will affect programs that are configured from here on, so you
-- should usually modify it before configuring any programs.
--
modifyProgramSearchPath :: (ProgramSearchPath -> ProgramSearchPath)
                        -> ProgramDb
                        -> ProgramDb
modifyProgramSearchPath f db =
  setProgramSearchPath (f $ getProgramSearchPath db) db

-- |User-specify this path.  Basically override any path information
-- for this program in the configuration. If it's not a known
-- program ignore it.
--
userSpecifyPath :: String   -- ^Program name
                -> FilePath -- ^user-specified path to the program
                -> ProgramDb -> ProgramDb
userSpecifyPath name path = updateUnconfiguredProgs $
  flip Map.update name $ \(prog, _, args) -> Just (prog, Just path, args)

userMaybeSpecifyPath :: String -> Maybe FilePath
                     -> ProgramDb -> ProgramDb
userMaybeSpecifyPath _    Nothing conf     = conf
userMaybeSpecifyPath name (Just path) conf = userSpecifyPath name path conf

-- |User-specify the arguments for this program.  Basically override
-- any args information for this program in the configuration. If it's
-- not a known program, ignore it..
userSpecifyArgs :: String    -- ^Program name
                -> [ProgArg] -- ^user-specified args
                -> ProgramDb
                -> ProgramDb
userSpecifyArgs name args' =
    updateUnconfiguredProgs
      (flip Map.update name $
         \(prog, path, args) -> Just (prog, path, args ++ args'))
  . updateConfiguredProgs
      (flip Map.update name $
         \prog -> Just prog { programOverrideArgs = programOverrideArgs prog
                                                 ++ args' })

-- | Like 'userSpecifyPath' but for a list of progs and their paths.
--
userSpecifyPaths :: [(String, FilePath)]
                 -> ProgramDb
                 -> ProgramDb
userSpecifyPaths paths conf =
  foldl' (\conf' (prog, path) -> userSpecifyPath prog path conf') conf paths

-- | Like 'userSpecifyPath' but for a list of progs and their args.
--
userSpecifyArgss :: [(String, [ProgArg])]
                 -> ProgramDb
                 -> ProgramDb
userSpecifyArgss argss conf =
  foldl' (\conf' (prog, args) -> userSpecifyArgs prog args conf') conf argss

-- | Get the path that has been previously specified for a program, if any.
--
userSpecifiedPath :: Program -> ProgramDb -> Maybe FilePath
userSpecifiedPath prog =
  join . fmap (\(_,p,_)->p) . Map.lookup (programName prog) . unconfiguredProgs

-- | Get any extra args that have been previously specified for a program.
--
userSpecifiedArgs :: Program -> ProgramDb -> [ProgArg]
userSpecifiedArgs prog =
  maybe [] (\(_,_,as)->as) . Map.lookup (programName prog) . unconfiguredProgs

-- -----------------------------
-- Managing configured programs

-- | Try to find a configured program
lookupProgram :: Program -> ProgramDb -> Maybe ConfiguredProgram
lookupProgram prog = Map.lookup (programName prog) . configuredProgs

-- | Update a configured program in the database.
updateProgram :: ConfiguredProgram -> ProgramDb
                                   -> ProgramDb
updateProgram prog = updateConfiguredProgs $
  Map.insert (programId prog) prog

-- | List all configured programs.
configuredPrograms :: ProgramDb -> [ConfiguredProgram]
configuredPrograms = Map.elems . configuredProgs

-- ---------------------------
-- Configuring known programs

-- | Try to configure a specific program. If the program is already included in
-- the collection of unconfigured programs then we use any user-supplied
-- location and arguments. If the program gets configured successfully it gets
-- added to the configured collection.
--
-- Note that it is not a failure if the program cannot be configured. It's only
-- a failure if the user supplied a location and the program could not be found
-- at that location.
--
-- The reason for it not being a failure at this stage is that we don't know up
-- front all the programs we will need, so we try to configure them all.
-- To verify that a program was actually successfully configured use
-- 'requireProgram'.
--
configureProgram :: Verbosity
                 -> Program
                 -> ProgramDb
                 -> IO ProgramDb
configureProgram verbosity prog conf = do
  let name = programName prog
  maybeLocation <- case userSpecifiedPath prog conf of
    Nothing   -> programFindLocation prog verbosity (progSearchPath conf)
             >>= return . fmap FoundOnSystem
    Just path -> do
      absolute <- doesExecutableExist path
      if absolute
        then return (Just (UserSpecified path))
        else findProgramOnSearchPath verbosity (progSearchPath conf) path
         >>= maybe (die notFound) (return . Just . UserSpecified)
      where notFound = "Cannot find the program '" ++ name
                     ++ "'. User-specified path '"
                     ++ path ++ "' does not refer to an executable and "
                     ++ "the program is not on the system path."
  case maybeLocation of
    Nothing -> return conf
    Just location -> do
      version <- programFindVersion prog verbosity (locationPath location)
      newPath <- programSearchPathAsPATHVar (progSearchPath conf)
      let configuredProg        = ConfiguredProgram {
            programId           = name,
            programVersion      = version,
            programDefaultArgs  = [],
            programOverrideArgs = userSpecifiedArgs prog conf,
            programOverrideEnv  = [("PATH", Just newPath)],
            programProperties   = Map.empty,
            programLocation     = location
          }
      configuredProg' <- programPostConf prog verbosity configuredProg
      return (updateConfiguredProgs (Map.insert name configuredProg') conf)

-- | Configure a bunch of programs using 'configureProgram'. Just a 'foldM'.
--
configurePrograms :: Verbosity
                  -> [Program]
                  -> ProgramDb
                  -> IO ProgramDb
configurePrograms verbosity progs conf =
  foldM (flip (configureProgram verbosity)) conf progs

-- | Try to configure all the known programs that have not yet been configured.
--
configureAllKnownPrograms :: Verbosity
                          -> ProgramDb
                          -> IO ProgramDb
configureAllKnownPrograms verbosity conf =
  configurePrograms verbosity
    [ prog | (prog,_,_) <- Map.elems notYetConfigured ] conf
  where
    notYetConfigured = unconfiguredProgs conf
      `Map.difference` configuredProgs conf

-- | reconfigure a bunch of programs given new user-specified args. It takes
-- the same inputs as 'userSpecifyPath' and 'userSpecifyArgs' and for all progs
-- with a new path it calls 'configureProgram'.
--
reconfigurePrograms :: Verbosity
                    -> [(String, FilePath)]
                    -> [(String, [ProgArg])]
                    -> ProgramDb
                    -> IO ProgramDb
reconfigurePrograms verbosity paths argss conf = do
  configurePrograms verbosity progs
   . userSpecifyPaths paths
   . userSpecifyArgss argss
   $ conf

  where
    progs = catMaybes [ lookupKnownProgram name conf | (name,_) <- paths ]

-- | Check that a program is configured and available to be run.
--
-- It raises an exception if the program could not be configured, otherwise
-- it returns the configured program.
--
requireProgram :: Verbosity -> Program -> ProgramDb
               -> IO (ConfiguredProgram, ProgramDb)
requireProgram verbosity prog conf = do

  -- If it's not already been configured, try to configure it now
  conf' <- case lookupProgram prog conf of
    Nothing -> configureProgram verbosity prog conf
    Just _  -> return conf

  case lookupProgram prog conf' of
    Nothing             -> die notFound
    Just configuredProg -> return (configuredProg, conf')

  where notFound       = "The program '" ++ programName prog
                      ++ "' is required but it could not be found."

-- | Check that a program is configured and available to be run.
--
-- Additionally check that the program version number is suitable and return
-- it. For example you could require 'AnyVersion' or @'orLaterVersion'
-- ('Version' [1,0] [])@
--
-- It returns the configured program, its version number and a possibly updated
-- 'ProgramDb'. If the program could not be configured or the version is
-- unsuitable, it returns an error value.
--
lookupProgramVersion
  :: Verbosity -> Program -> VersionRange -> ProgramDb
  -> IO (Either String (ConfiguredProgram, Version, ProgramDb))
lookupProgramVersion verbosity prog range programDb = do

  -- If it's not already been configured, try to configure it now
  programDb' <- case lookupProgram prog programDb of
    Nothing -> configureProgram verbosity prog programDb
    Just _  -> return programDb

  case lookupProgram prog programDb' of
    Nothing                           -> return $! Left notFound
    Just configuredProg@ConfiguredProgram { programLocation = location } ->
      case programVersion configuredProg of
        Just version
          | withinRange version range ->
            return $! Right (configuredProg, version ,programDb')
          | otherwise                 ->
            return $! Left (badVersion version location)
        Nothing                       ->
          return $! Left (noVersion location)

  where notFound       = "The program '"
                      ++ programName prog ++ "'" ++ versionRequirement
                      ++ " is required but it could not be found."
        badVersion v l = "The program '"
                      ++ programName prog ++ "'" ++ versionRequirement
                      ++ " is required but the version found at "
                      ++ locationPath l ++ " is version " ++ display v
        noVersion l    = "The program '"
                      ++ programName prog ++ "'" ++ versionRequirement
                      ++ " is required but the version of "
                      ++ locationPath l ++ " could not be determined."
        versionRequirement
          | isAnyVersion range = ""
          | otherwise          = " version " ++ display range

-- | Like 'lookupProgramVersion', but raises an exception in case of error
-- instead of returning 'Left errMsg'.
--
requireProgramVersion :: Verbosity -> Program -> VersionRange
                      -> ProgramDb
                      -> IO (ConfiguredProgram, Version, ProgramDb)
requireProgramVersion verbosity prog range programDb =
  join $ either die return <$>
  lookupProgramVersion verbosity prog range programDb


text:
// This file contains the patterns to convert arith.index_cast on tensors to
// tensor ops and index_cast on scalars.

#include <utility>

#include "mlir-hlo/Transforms/passes.h"
#include "mlir/Dialect/Arith/IR/Arith.h"
#include "mlir/Dialect/Func/IR/FuncOps.h"
#include "mlir/Dialect/Tensor/IR/Tensor.h"
#include "mlir/Dialect/Tensor/Utils/Utils.h"
#include "mlir/IR/PatternMatch.h"
#include "mlir/Transforms/GreedyPatternRewriteDriver.h"

namespace mlir {

#define GEN_PASS_DEF_LOWERINDEXCASTPASS
#include "mlir-hlo/Transforms/passes.h.inc"

namespace {

// index_cast is not defined on tensors, so lower it to a tensor.generate.
struct IndexCastConverter : public OpRewritePattern<arith::IndexCastOp> {
 public:
  using OpRewritePattern::OpRewritePattern;
  LogicalResult matchAndRewrite(arith::IndexCastOp op,
                                PatternRewriter &rewriter) const final {
    auto resultTy = op.getType().dyn_cast<RankedTensorType>();
    if (!resultTy) return failure();

    SmallVector<Value> dynamicExtents =
        tensor::createDynamicDimValues(rewriter, op.getLoc(), op.getIn());
    rewriter.replaceOpWithNewOp<tensor::GenerateOp>(
        op, resultTy, dynamicExtents,
        [&](OpBuilder &b, Location loc, ValueRange args) {
          Value extent = b.create<tensor::ExtractOp>(loc, op.getIn(), args);
          Value cast = b.create<arith::IndexCastOp>(
              loc, resultTy.getElementType(), extent);
          b.create<tensor::YieldOp>(loc, cast);
        });
    return success();
  }
};

struct LowerIndexCastPass
    : public impl::LowerIndexCastPassBase<LowerIndexCastPass> {
  void runOnOperation() override {
    RewritePatternSet patterns(&getContext());
    patterns.add<IndexCastConverter>(patterns.getContext());
    if (failed(
            applyPatternsAndFoldGreedily(getOperation(), std::move(patterns))))
      return signalPassFailure();
  }
};

}  // namespace

std::unique_ptr<OperationPass<func::FuncOp>> createLowerIndexCastPass() {
  return std::make_unique<LowerIndexCastPass>();
}

}  // namespace mlir

redpajama_set_name: RedPajamaGithub


text:
using ASummonersTale.TileEngine;
using System.Collections.Generic;

namespace ASummonersTale.Components
{
    internal class LevelManager
    {
        private Dictionary<int, TileMap> levels;

        public LevelManager()
        {
            levels = new Dictionary<int, TileMap>();
        }

        public TileMap this[int level]
        {
            get
            {
                return levels[level];
            }

            set
            {
                levels.Add(level, value);
            }
        }
    }
}


text:
\section{cachedDBM}\label{cachedDBM}

{\tt cachedDBM} implements a notion of persistent objects. First and
foremostly, it has the syntax of std::map, ie it is a template map
object, with a key and value type pair. However, by calling the
\verb+init()+ method, you can attach a database file, so that values
saved in the cachedDBM are stored on disk, to be accessible at a later
time.

The iterator range \verb+begin()+ to \verb+end()+ refers to everything
stored in the database. An alternative interface that iterates over
the database keys is provided by \verb+keys.begin()+ and
\verb+keys.end()+ The database is committed when \verb+begin()+ is
called, unless the database was opened readonly. In this latter case,
there are potentially items stored in the map which will not be
iterated over. The alternative iteration
methods \verb+firstkey()+, \verb+nextkey()+ and \verb+eof()+ is an
older interface for iterating over \verb+keys.begin()+ to
\verb+keys.end()+.  In this instance, the cachedDBM is not committed
when \verb+firstkey()+ is called.

Elements stored in the cachedDBM are not actually written to disk until
\verb+commit()+ is called (or the cachedDBM object is
destroyed).

Entries in the database can be removed via \verb+del()+. However, if
an item with the same key is in the cache, it will need to be removed via
\verb+erase()+ as well, otherwise it will be reinserted in the
database at commit time.

Only a very simple caching algorithm is employed, but it seems
sufficient for many purposes. If the member \verb+max_elem+ is set,
then this acts as an upper limit to the number of items stored in
memory. If you request a new item to be loaded via the [] operator,
and it will cause the number of items to be exceeded, the cachedDBM
object is committed. At least the oldest quarter of the cache is cleared,
and up to half of the cache. So if \verb+max_elem+=100, then one is
guaranteed that the previous 50 accessed objects will always be in
memory, so can be assigned to a reference.

Classdesc serialisation (XDR serialisation) is used store both keys
and value data. The database file are therefore machine independent.
As a special exception to serialisation rules, \verb+char*+ can be
used as key and data types.

\subsection{Synopsis}

\begin{verbatim}
template<class key, class val>
class cachedDBM_base : public base_map<key,val>
{
public:
  int max_elem;   /* limit number of elements to this value */
  void init(const char *fname, char mode='w'); /* open database file */
  void Init(TCL_args args); /* TCL access to init() */
  void close();    /* commit and close database file */
  bool opened();   /* is a database attached? */
  bool key_exists(const key& k); /* does the key exist in db */
  val& operator[] (const key& k); /* access element with key k */
  void commit();    /* write any changes out to the file, and clear cache */
  void del(key k); /* delete key from database (but not cache!) */
  key firstkey();  /* return first key in database */
  key nextkey();   /* return next key in database in an iteration */
  int eof();       /* true if all keys have been accessed */
  KeyValueIterator begin() const;
  KeyValueIterator end() const;
  KeyIterator keys.begin() const;
  KeyIterator keys.end() const;
};
\end{verbatim}

\subsection{TCL access}

cachedDBM objects are addressable from TCL. Individual
objects stored in the cachedDBM are addressable from TCL by means of
the \verb+elem()+ method, but also the following members are
exported to the TCL interface, allowing scripting access to
manipulating the database:

\begin{itemize}
\item \verb+cachedDBM::max_elem+
\item \verb+cachedDBM::Init+ {\em filename} {\em r$|$w}
\item \verb+cachedDBM::close+
\item \verb+cachedDBM::opened+
\item \verb+cachedDBM::elem+ With one argument, get the element value,
  with two arguments, set it.
\item \verb+cachedDBM::commit+
\item \verb+cachedDBM::firstkey+
\item \verb+cachedDBM::nextkey+
\item \verb+cachedDBM::eof+
\end{itemize}

\subsection{Types of database}

By default, if EcoLab's Makefile detects the presence of Berkeley DB on
your system, it will be used. Otherwise it use the ndbm API. If
libgdbm and/or libgdbm\_compat (the NDBM compatibility layer in GDBM)
these will be added to the linker flags, otherwise it will assume that
ndbm is available as part of the standard system library.

You can't mix and match database types. If you have some data stored
in one type, and need to access it using a different database type,
the utilities convtoNDBM and convtoBDB found in the util directory may
be useful.


text:
Note: The solutions are tested using [jest](http://facebook.github.io/jest/) from Facebook.

To run the test script:

```
npm install
npm test

```


text:
<!DOCTYPE html>

  <link href="http://gmpg.org/xfn/11" rel="profile">
  <meta http-equiv="content-type" content="text/html; charset=utf-8">
  <meta name="generator" content="Hugo 0.16-DEV" />

  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1">

  <title>Golang introducing HTTP tracing · 钱国正博客</title>

<link rel="stylesheet" href="/css/monokai.css">

  <link rel="stylesheet" href="https://qianguozheng.github.io/css/poole.css">
  <link rel="stylesheet" href="https://qianguozheng.github.io/css/syntax.css">
  <link rel="stylesheet" href="https://qianguozheng.github.io/css/hyde.css">
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=PT+Sans:400,400italic,700|Abril+Fatface">

  <link rel="apple-touch-icon-precomposed" sizes="144x144" href="/apple-touch-icon-144-precomposed.png">
  <link rel="shortcut icon" href="/favicon.png">

  <link href="" rel="alternate" type="application/rss+xml" title="钱国正博客" />

钱国正博客

      An elegant open source and mobile first theme for hugo made by @mdo. Originally made for Jekyll.

Home

 Golang gorilla context doc

 Golang gorilla mux

 Golang introducing HTTP tracing

 Golang iotuils devnull deserve deep thinking

 Golang recover usage

 Golang session problem

 Linux getsockopt sample usage

 control loop at html template in golang

 go ethereum create your own account

 go ethereum crypto private public key

 hugo deploy as submodule on github

 netfilter xt_recent

© 2018. All rights reserved.

Golang introducing HTTP tracing

			  Fri, Jan 20, 2017

介绍

在Go 1.7我们引入了HTTP跟踪, 用来收集HTTP客户端请求生命周期中详细信息的工作。包在net/http/httptrace. 手机的信息可以用来调试延时问题,服务监控,写适配系统等。

HTTP 事件

httptrace包提供了许多钩子在HTTP生命周期中收集信息。这些事件包括:

Connection creation

Connection reuse

DNS lookups

Writing the request to the wire

Reading the response

跟踪事件

你可以通过放置一个*httptrace.ClientTrace 包含钩子函数在请求的context.Context中来开启http追踪。各种http.RoundTripper实现通过查找上下文的 *httptrace.ClientTrace和调用相关的钩子函数来汇报内部事件

最终作用于请求的上下文,用户应该将一个 *httptrace.ClientTrace防到请求的上下文在开始请求之前。

    req, _ := http.NewRequest("GET", "http://example.com", nil)
    trace := &httptrace.ClientTrace{
        DNSDone: func(dnsInfo httptrace.DNSDoneInfo) {
            fmt.Printf("DNS Info: %+v\n", dnsInfo)
        },
        GotConn: func(connInfo httptrace.GotConnInfo) {
            fmt.Printf("Got Conn: %+v\n", connInfo)
        },
    }
    req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace))
    if _, err := http.DefaultTransport.RoundTrip(req); err != nil {
        log.Fatal(err)
    }

在请求流程中,http.DefaultTransport会在事件发生时出发钩子。上面的程序会打印DNS信息当DNS查询完成时。同样的会打印连接信息当链接与请求主机建立连接时

使用http.Client跟踪

跟踪机制设计用来跟踪单个的http.Transport.RoundTrip的声明周期事件。然而,一个客户端可以发起多个round trips来完成HTTP请求。例如,URL重定向,注册的钩子被调用多次当客户端跟踪HTTP重定向,发起多个请求。用户负责识别类似的事件在http.CLient中。下面的程序识别通过httpRoundTripper包裹识别当前的请求。

package main

import (
    "fmt"
    "log"
    "net/http"
    "net/http/httptrace"
)

// transport is an http.RoundTripper that keeps track of the in-flight
// request and implements hooks to report HTTP tracing events.
type transport struct {
    current *http.Request
}

// RoundTrip wraps http.DefaultTransport.RoundTrip to keep track
// of the current request.
func (t *transport) RoundTrip(req *http.Request) (*http.Response, error) {
    t.current = req
    return http.DefaultTransport.RoundTrip(req)
}

// GotConn prints whether the connection has been used previously
// for the current request.
func (t *transport) GotConn(info httptrace.GotConnInfo) {
    fmt.Printf("Connection reused for %v? %v\n", t.current.URL, info.Reused)
}

func main() {
    t := &transport{}

    req, _ := http.NewRequest("GET", "https://google.com", nil)
    trace := &httptrace.ClientTrace{
        GotConn: t.GotConn,
    }
    req = req.WithContext(httptrace.WithClientTrace(req.Context(), trace))

    client := &http.Client{Transport: t}
    if _, err := client.Do(req); err != nil {
        log.Fatal(err)
    }
}

程序将会跟踪重定向google.com 到www.google.com并打印如下:

Connection reused for https://google.com? false
Connection reused for https://www.google.com/? false

传输在net/http包支持跟踪http/1和http/2

如果你是一个定制的http.RoundTripper实现作者,你可以通过检查请求上下文并在相应的事件发生时触发钩子函数

结论

GO的HTTP跟踪对于那些感兴趣调试HTTP请求延时和些网络外部负载调试工具时。 通过开启这个功能,我们希望可以看到HTTP调试,性能。可视化工具来自社区例如httpstat.

By Jaana Burcu Dogan

Comments

Please enable JavaScript to view the comments powered by Disqus.


text:
#include <aws/ssm-contacts/model/AcceptPageResult.h>
#include <aws/core/utils/json/JsonSerializer.h>
#include <aws/core/AmazonWebServiceResult.h>
#include <aws/core/utils/StringUtils.h>
#include <aws/core/utils/UnreferencedParam.h>

#include <utility>

using namespace Aws::SSMContacts::Model;
using namespace Aws::Utils::Json;
using namespace Aws::Utils;
using namespace Aws;

AcceptPageResult::AcceptPageResult()
{
}

AcceptPageResult::AcceptPageResult(const Aws::AmazonWebServiceResult<JsonValue>& result)
{
  *this = result;
}

AcceptPageResult& AcceptPageResult::operator =(const Aws::AmazonWebServiceResult<JsonValue>& result)
{
  AWS_UNREFERENCED_PARAM(result);

  return *this;
}


text:
package boofcv.alg.geo.calibration;

import boofcv.alg.geo.h.HomographyLinear4;
import boofcv.struct.geo.AssociatedPair;
import georegression.struct.point.Point2D_F64;
import org.ejml.data.DenseMatrix64F;

import java.util.ArrayList;
import java.util.List;

/**
 *

 * Given a description of the calibration grid and a set of observations compute the associated Homography.
 * First a linear approximation is computed follow by non-linear refinement.  Part of calibration process
 * described in [1].
 *

 *
 *

 * [1] Zhengyou Zhang, "Flexible Camera Calibration By Viewing a Plane From Unknown Orientations,",
 * International Conference on Computer Vision (ICCV'99), Corfu, Greece, pages 666-673, September 1999.99
 *

 *
 * @author Peter Abeles
 */
public class Zhang99ComputeTargetHomography {

	HomographyLinear4 linear = new HomographyLinear4(true);
	DenseMatrix64F found = new DenseMatrix64F(3,3);

	// location of grid coordinates in the world frame.
	// the z-axis is assumed to be zero
	List<Point2D_F64> worldPoints;

	public Zhang99ComputeTargetHomography(PlanarCalibrationTarget config) {
		this.worldPoints = config.points;
	}

	/**
	 * Computes the homography from a list of detected grid points in the image.  The
	 * order of the grid points is important and must follow the expected row major
	 * starting at the top left.
	 *
	 * @param observedPoints List of ordered detected grid points in image pixels.
	 * @return True if it computed a Homography and false if it failed to compute a homography matrix.
	 */
	public boolean computeHomography( List<Point2D_F64> observedPoints )
	{
		if( observedPoints.size() != worldPoints.size() )
			throw new IllegalArgumentException("Unexpected number of grid points.");

		List<AssociatedPair> pairs = new ArrayList<AssociatedPair>();
		for( int i = 0; i < observedPoints.size(); i++ ) {
			pairs.add( new AssociatedPair(worldPoints.get(i),observedPoints.get(i),true));
		}

		if( !linear.process(pairs,found) )
			return false;

		// todo do non-linear refinement.  Take advantage of coordintes being fixed

		return true;
	}

	/**
	 * Returns a copy of the found homography matrix.
	 * @return Homography matrix.
	 */
	public DenseMatrix64F getHomography() {
		return found.copy();
	}
}


text:
<?php

/* @Page:C:\xampp\htdocs\ccp\user\plugins\error/pages */
class __TwigTemplate_2170f9d57c8c22e31f3d5123e3b8b502e9dec06322cf696722b3a1c61dddf8d0 extends Twig_Template
{
    public function __construct(Twig_Environment $env)
    {
        parent::__construct($env);

        $this->parent = false;

        $this->blocks = array(
        );
    }

    protected function doDisplay(array $context, array $blocks = array())
    {
        // line 1
        echo $this->env->getExtension('Grav\Common\Twig\TwigExtension')->translate("PLUGIN_ERROR.ERROR_MESSAGE");
        echo "

";
    }

    public function getTemplateName()
    {
        return "@Page:C:\\xampp\\htdocs\\ccp\\user\\plugins\\error/pages";
    }

    public function isTraitable()
    {
        return false;
    }

    public function getDebugInfo()
    {
        return array (  19 => 1,);
    }

    public function getSource()
    {
        return "{{ 'PLUGIN_ERROR.ERROR_MESSAGE'|t }}

";
    }
}


text:
using System;
using System.Collections.Generic;
using System.Text;

namespace VEngine
{
    public class Mesh3dInstance : ITransformable
    {
        public uint Id;
        public string Name;
        public TransformationManager Transformation;

        public Mesh3dInstance(TransformationManager trans, string name)
        {
            Transformation = trans;
            Name = name;
            Id = ObjectIDGenerator.GetNext();
        }

        public TransformationManager GetTransformationManager()
        {
            return Transformation;
        }
    }
}


text:
package com.wso2telco.core.config.model;

import org.wso2.carbon.identity.application.authentication.framework.exception.AuthenticationFailedException;

/**
 * Created by isuru on 1/2/17.
 */
public class PinConfig {

    private String msisdn;

    private String sessionId;

    private int totalAttempts;

    private int invalidFormatAttempts;

    private int pinMismatchAttempts;

    private String registeredPin;

    private String confirmedPin;

    private CurrentStep currentStep;

    private String challengeQuestion1;

    private String challengeQuestion2;

    private String challengeAnswer1;

    private String challengeAnswer2;

    public void incrementTotatAttempts() {
        totalAttempts++;
    }

    public void incrementInvalidFormatAttempts() {
        invalidFormatAttempts++;
    }

    public void incrementPinMistmachAttempts() {
        pinMismatchAttempts++;
    }

    public String getRegisteredPin() {
        return registeredPin;
    }

    public void setRegisteredPin(String registeredPin) {
        this.registeredPin = registeredPin;
    }

    public String getConfirmedPin() {
        return confirmedPin;
    }

    public void setConfirmedPin(String confirmedPin) {
        this.confirmedPin = confirmedPin;
    }

    public String getMsisdn() {
        return msisdn;
    }

    public void setMsisdn(String msisdn) {
        this.msisdn = msisdn;
    }

    public String getSessionId() {
        return sessionId;
    }

    public void setSessionId(String sessionId) {
        this.sessionId = sessionId;
    }

    public int getTotalAttempts() {
        return totalAttempts;
    }

    public void setTotalAttempts(int totalAttempts) {
        this.totalAttempts = totalAttempts;
    }

    public int getInvalidFormatAttempts() {
        return invalidFormatAttempts;
    }

    public void setInvalidFormatAttempts(int invalidFormatAttempts) {
        this.invalidFormatAttempts = invalidFormatAttempts;
    }

    public int getPinMismatchAttempts() {
        return pinMismatchAttempts;
    }

    public void setPinMismatchAttempts(int pinMismatchAttempts) {
        this.pinMismatchAttempts = pinMismatchAttempts;
    }

    public boolean isPinsMatched() throws AuthenticationFailedException {
        if (confirmedPin != null && registeredPin != null) {
            return registeredPin.equalsIgnoreCase(confirmedPin);
        } else {
            throw new AuthenticationFailedException("Did not receive pin response");
        }
    }

    public String getChallengeQuestion1() {
        return challengeQuestion1;
    }

    public void setChallengeQuestion1(String challengeQuestion1) {
        this.challengeQuestion1 = challengeQuestion1;
    }

    public String getChallengeQuestion2() {
        return challengeQuestion2;
    }

    public String getChallengeAnswer1() {
        return challengeAnswer1;
    }

    public void setChallengeAnswer1(String challengeAnswer1) {
        this.challengeAnswer1 = challengeAnswer1;
    }

    public String getChallengeAnswer2() {
        return challengeAnswer2;
    }

    public void setChallengeAnswer2(String challengeAnswer2) {
        this.challengeAnswer2 = challengeAnswer2;
    }

    public void setChallengeQuestion2(String challengeQuestion2) {
        this.challengeQuestion2 = challengeQuestion2;
    }

    public CurrentStep getCurrentStep() {
        return currentStep;
    }

    public void setCurrentStep(CurrentStep currentStep) {
        this.currentStep = currentStep;
    }

    public enum CurrentStep {
        REGISTRATION,
        CONFIRMATION,
        LOGIN,
        PIN_RESET,
        PIN_RESET_CONFIRMATION
    }
}


text:
<?php
require_once('authorize.php') ;
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <title>Gravitas - Admin Page</title>
  <link rel="stylesheet" type="text/css" href="style.css" />

Gravitas - Registration Admin Page

<?php
   //connecting to database
    $dbc = mysqli_connect('localhost', 'root', '', 'gravitas1') or die("Error connecting to the database");

	echo '
See Details By
 ' ;
	echo 'Event' ;
	echo 'College' ;
	echo 'Date' ;

	$query = "Select sum(p_male) AS sum from team" ;
	$data = mysqli_query($dbc, $query) or die('Error finding total number of male participants.') ;
	$row = mysqli_fetch_array($data) ;
	$total_male_p = $row['sum'] ;

	$query = "Select sum(p_female) AS sum from team" ;
	$data = mysqli_query($dbc, $query) or die('Error finding total number of female participants.') ;
	$row = mysqli_fetch_array($data) ;
	$total_female_p = $row['sum'] ;

	$total_p = $total_male_p + $total_female_p ;

	$query = "Select sum(total) AS sum from payment" ;
	$data = mysqli_query($dbc, $query) or die('Error finding total amount.') ;
	$row = mysqli_fetch_array($data) ;
	$total_amnt = $row['sum'] ;

	echo '
Event Registration Highlights
' ;
	echo '
' ;
	echo 'Total number of participants: ' . $total_p . '
';
	echo 'Total number of female participants: ' .$total_female_p . '
';
	echo 'Total number of male participants: ' . $total_male_p . '
';
	echo 'Total money collected :Rs ' . $total_amnt ;
	echo '
' ;

	require_once('footer.php');
?>


text:
'use strict'
var path = require('path')
var fs = require('fs')
var test = require('tap').test
var osenv = require('osenv')
var mkdirp = require('mkdirp')
var rimraf = require('rimraf')
var common = require('../common-tap.js')

var base = path.join(__dirname, path.basename(__filename, '.js'))
var installFrom = path.join(base, 'from')
var installIn = path.join(base, 'in')

var json = {
  name: 'check-install-self',
  version: '0.0.1',
  description: 'fixture'
}

test('setup', function (t) {
  setup()
  t.end()
})

var INSTALL_OPTS = ['--loglevel', 'silent']
var EXEC_OPTS = {cwd: installIn}

test('install self', function (t) {
  common.npm(['install', installFrom].concat(INSTALL_OPTS), EXEC_OPTS, function (err, code) {
    t.ifError(err, 'npm ran without issue')
    t.is(code, 1, 'npm install refused to install a package in itself')
    t.end()
  })
})
test('force install self', function (t) {
  common.npm(['install', '--force', installFrom].concat(INSTALL_OPTS), EXEC_OPTS, function (err, code) {
    t.ifError(err, 'npm ran without issue')
    t.is(code, 0, 'npm install happily installed a package in itself with --force')
    t.end()
  })
})

test('cleanup', function (t) {
  cleanup()
  t.end()
})

function cleanup () {
  process.chdir(osenv.tmpdir())
  rimraf.sync(base)
}

function setup () {
  cleanup()
  mkdirp.sync(path.resolve(installFrom, 'node_modules'))
  fs.writeFileSync(
    path.join(installFrom, 'package.json'),
    JSON.stringify(json, null, 2)
  )
  mkdirp.sync(path.resolve(installIn, 'node_modules'))
  fs.writeFileSync(
    path.join(installIn, 'package.json'),
    JSON.stringify(json, null, 2)
  )
  process.chdir(base)
}


text:
jQuery.fn.countdown = function(userOptions)
{
  // Default options
  var options = {
    stepTime: 60,
    // startTime and format MUST follow the same format.
    // also you cannot specify a format unordered (e.g. hh:ss:mm is wrong)
    format: "dd:hh:mm:ss",
    startTime: "01:12:32:55",
    digitImages: 6,
    digitWidth: 53,
    digitHeight: 77,
    timerEnd: function(){},
    image: "digits.png"
  };
  var digits = [], interval;

  // Draw digits in given container
  var createDigits = function(where)
  {
    var c = 0;
    // Iterate each startTime digit, if it is not a digit
    // we'll asume that it's a separator
    for (var i = 0; i < options.startTime.length; i++)
    {
      if (parseInt(options.startTime[i]) >= 0)
      {
        elem = $('
').css({
          height: options.digitHeight * options.digitImages * 10,
          float: 'left', background: 'url(\'' + options.image + '\')',
          width: options.digitWidth});
        digits.push(elem);
        margin(c, -((parseInt(options.startTime[i]) * options.digitHeight *
                              options.digitImages)));
        digits[c].__max = 9;
        // Add max digits, for example, first digit of minutes (mm) has
        // a max of 5. Conditional max is used when the left digit has reach
        // the max. For example second "hours" digit has a conditional max of 4
        switch (options.format[i]) {
          case 'h':
            digits[c].__max = (c % 2 == 0) ? 2: 9;
            if (c % 2 == 0)
              digits[c].__condmax = 4;
            break;
          case 'd':
            digits[c].__max = 9;
            break;
          case 'm':
          case 's':
            digits[c].__max = (c % 2 == 0) ? 5: 9;
        }
        ++c;
      }
      else
        elem = $('
').css({float: 'left'})
                .text(options.startTime[i]);

      where.append(elem)
    }
  };

  // Set or get element margin
  var margin = function(elem, val)
  {
    if (val !== undefined)
      return digits[elem].css({'marginTop': val + 'px'});

    return parseInt(digits[elem].css('marginTop').replace('px', ''));
  };

  // Makes the movement. This is done by "digitImages" steps.
  var moveStep = function(elem)
  {
    digits[elem]._digitInitial = -(digits[elem].__max * options.digitHeight * options.digitImages);
    return function _move() {
      mtop = margin(elem) + options.digitHeight;
      if (mtop == options.digitHeight) {
        margin(elem, digits[elem]._digitInitial);
        if (elem > 0) moveStep(elem - 1)();
        else
        {
          clearInterval(interval);
          for (var i=0; i < digits.length; i++) margin(i, 0);
          options.timerEnd();
          return;
        }
        if ((elem > 0) && (digits[elem].__condmax !== undefined) &&
            (digits[elem - 1]._digitInitial == margin(elem - 1)))
          margin(elem, -(digits[elem].__condmax * options.digitHeight * options.digitImages));
        return;
      }

      margin(elem, mtop);
      if (margin(elem) / options.digitHeight % options.digitImages != 0)
        setTimeout(_move, options.stepTime);

      if (mtop == 0) digits[elem].__ismax = true;
    }
  };

  $.extend(options, userOptions);
  this.css({height: options.digitHeight, overflow: 'hidden'});
  createDigits(this);
  interval = setInterval(moveStep(digits.length - 1), 1000);
};


text:
Your profile

	<form id="profileForm" name="profileForm">
		<fieldset>
			<legend>Account Information</legend>

				Login *:
				<input type="text" id="fieldLogin" name="fieldLogin" ng-model="user.login"/>

				Password *:
				<input type="password" id="fieldPassword" ng-model="user.password"/>

				Email Address *:
				<input type="text" id="fieldEmail" ng-model="user.mail"/>

		</fieldset>

		<fieldset ng-repeat="address in user.addresses">
			<legend>Address {{$index + 1}}</legend>

				First Name:
				<input type="text" id="fieldFirstName" ng-model="address.firstName"/>

				Last Name:
				<input type="text" id="fieldLastName" ng-model="address.lastName"/>

				Address:
				<input type="text" id="fieldAddress" ng-model="address.address"/>

				Postal Code:
				<input type="text" id="fieldPostalCode" ng-model="address.postalCode"/>

				Town:
				<input type="text" id="fieldTown" ng-model="address.town"/>

				Default address:
				<input type="checkbox" id="fieldDefault" ng-model="address.isDefault"/>

		</fieldset>

			<button class="btn" ng-click="updateUser()">Update profile</button>

	</form>


text:
package com.zjw.weather;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.thinkland.juheapi.common.JsonCallBack;
import com.thinkland.juheapi.data.air.AirData;
import com.thinkland.juheapi.data.weather.WeatherData;
import com.zjw.weather.bean.FutureWeatherBean;
import com.zjw.weather.bean.HoursWeatherBean;
import com.zjw.weather.bean.PmWeatherBean;
import com.zjw.weather.bean.WeatherBean;
import com.zjw.weather.service.WeatherService;
import com.zjw.weather.service.WeatherService.CallBack;
import com.zjw.weather.service.WeatherService.WeatherServiceBinder;
import com.zjw.weather.swiperefresh.PullToRefreshBase;
import com.zjw.weather.swiperefresh.PullToRefreshBase.OnRefreshListener;
import com.zjw.weather.swiperefresh.PullToRefreshScrollView;

import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

public class ActivityWeather extends Activity {
	private PullToRefreshScrollView mPullToRefreshScrollView;
	private ScrollView mScrollView;
	private WeatherService mService;

	private TextView tv_city,
	tv_release,
	tv_now_weather,
	tv_today_temp,
	tv_now_temp,
	tv_aqi,
	tv_quality,
	tv_next_3,
	tv_next_6,
	tv_next_9,
	tv_next_12,
	tv_next_15,
	tv_next_3_tmp,
	tv_next_6_tmp,
	tv_next_9_tmp,
	tv_next_12_tmp,
	tv_next_15_tmp,
	tv_today_temp_a,
	tv_today_temp_b,
	tv_tommorrow,
	tv_tommorrow_temp_a,
	tv_tommorrow_temp_b,
	tv_3rd_day,
	tv_3rd_temp_a,
	tv_3rd_temp_b,
	tv_4th_day,
	tv_4th_temp_a,
	tv_4th_temp_b,
	tv_felt_air_temp,
	tv_humidity,
	tv_wind,
	tv_uv_index,
	tv_dressing_index;

	private ImageView iv_now_weather,
	iv_next_3,
	iv_next_6,
	iv_next_9,
	iv_next_12,
	iv_next_15,
	iv_today_weather,
	iv_tommorrow_weather,
	iv_3rd_weather,
	iv_4th_weather;

	private RelativeLayout rl_city;

	ServiceConnection conn = new ServiceConnection() {

		@Override
		public void onServiceDisconnected(ComponentName name) {
			mService.removeCallback();
		}

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			WeatherServiceBinder binder = (WeatherServiceBinder) service;
			mService = binder.getService();
//			mService.test();
			mService.setCallBack(new CallBack() {

				@Override
				public void onParseComplete(List<HoursWeatherBean> list,
						PmWeatherBean pmBean, WeatherBean weatherBean) {
					mPullToRefreshScrollView.onRefreshComplete();
					if (list != null && list.size() >= 5) {
						set3HourForcastView(list);
					}
					if (pmBean!= null) {
						setPmView(pmBean);
					}
					if (weatherBean!= null) {
						setView(weatherBean);
					}
				}
			});
			mService.getCityWeather();
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_mian);
		init();
//		getCityWeather();
		initService();
	}

	private void initService(){
		Intent intent = new Intent(this, WeatherService.class);
		startService(intent);
		bindService(intent, conn, Context.BIND_AUTO_CREATE);
	}

	private void setPmView(PmWeatherBean bean) {
		tv_aqi.setText(bean.getAqi());
		tv_quality.setText(bean.getQuality());

	}

	private void set3HourForcastView(List<HoursWeatherBean> list) {
		set3HourForcastData(tv_next_3, iv_next_3, tv_next_3_tmp, list.get(0));
		set3HourForcastData(tv_next_6, iv_next_6, tv_next_6_tmp, list.get(1));
		set3HourForcastData(tv_next_9, iv_next_9, tv_next_9_tmp, list.get(2));
		set3HourForcastData(tv_next_12, iv_next_12, tv_next_12_tmp, list.get(3));
		set3HourForcastData(tv_next_15, iv_next_15, tv_next_15_tmp, list.get(4));
	}
	private void set3HourForcastData(TextView tv1, ImageView iv, TextView tv2, HoursWeatherBean bean) {
		String preFix;
		int hour = Integer.valueOf(bean.getTime());
		if (hour >=6 && hour<18) {
			preFix = "d";
		}else {
			preFix = "n";
		}
		tv1.setText(bean.getTime());
		iv.setImageResource(getResources().getIdentifier(preFix+bean.getWeather_id(), "drawable", "com.zjw.weather"));
		tv2.setText(bean.getTemp()+"°");
	}

	private void setView(WeatherBean weatherBean) {
		tv_city.setText(weatherBean.getCity());
		tv_release.setText(weatherBean.getRelease());
		tv_now_weather.setText(weatherBean.getWeather_str());
		String replace = weatherBean.getTemp().replace("℃", "");
		String[] split = replace.split("~");
		String temp_str_a = split[0];
		String temp_str_b = split[1];
		tv_today_temp.setText("↓"+temp_str_a+"°"+" "+"↑"+temp_str_b+"°");//↓↑°   4℃~8℃
		tv_now_temp.setText(weatherBean.getNow_temp());

		Calendar c = Calendar.getInstance();
		int hour = c.get(Calendar.HOUR_OF_DAY);
		String preFix;
		if (hour >=6 && hour<18) {
			preFix = "d";
		}else {
			preFix = "n";
		}
		iv_today_weather.setImageResource(getResources().getIdentifier(preFix+weatherBean.getWeather_id(), "drawable", "com.zjw.weather"));
		tv_today_temp_a.setText(temp_str_a+"°");
		tv_today_temp_b.setText(temp_str_b+"°");
		List<FutureWeatherBean> futureList = weatherBean.getFutureLists();
		if (futureList.size() == 3) {
			setFutureData(tv_tommorrow, iv_tommorrow_weather, tv_tommorrow_temp_a, tv_tommorrow_temp_b, futureList.get(0));
			setFutureData(tv_3rd_day, iv_3rd_weather, tv_3rd_temp_a, tv_3rd_temp_b, futureList.get(1));
			setFutureData(tv_4th_day, iv_4th_weather, tv_4th_temp_a, tv_4th_temp_b, futureList.get(2));
		}

		iv_now_weather.setImageResource(getResources().getIdentifier(preFix+weatherBean.getWeather_id(), "drawable", "com.zjw.weather"));
		tv_humidity.setText(weatherBean.getHumidity());
		tv_dressing_index.setText(weatherBean.getDressing_index());
		tv_uv_index.setText(weatherBean.getUv_index());
		tv_wind.setText(weatherBean.getWind());
//		tv_felt_air_temp.setText(weatherBean.getFelt_temp());
	}

	public void setFutureData(TextView tv_week, ImageView iv_weather, TextView tv_temp_a,TextView tv_temp_b, FutureWeatherBean bean) {
		tv_week.setText(bean.getWeek());
		iv_weather.setImageResource(getResources().getIdentifier("d"+bean.getWeather_id(), "drawable", "com.zjw.weather"));
		String replace = bean.getTemp().replace("℃", "");
		String[] split = replace.split("~");
		String temp_str_a = split[0];
		String temp_str_b = split[1];
		tv_temp_a.setText(temp_str_a+"°");
		tv_temp_b.setText(temp_str_b+"°");
	}

	public void init(){
		mPullToRefreshScrollView = (PullToRefreshScrollView) findViewById(R.id.pull_refresh_scrollview);
		mPullToRefreshScrollView.setOnRefreshListener(new OnRefreshListener<ScrollView>() {

			@Override
			public void onRefresh(PullToRefreshBase<ScrollView> refreshView) {
//				getCityWeather();
				mService.getCityWeather();
			}
		});

		//通过第三方控件获取mScrollView
		mScrollView = mPullToRefreshScrollView.getRefreshableView();

		rl_city = (RelativeLayout) findViewById(R.id.rl_city);
		rl_city.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				Intent intent = new Intent(ActivityWeather.this, CityActivity.class);
				startActivityForResult(intent, 1);
			}
		});

		tv_city = (TextView) findViewById(R.id.tv_city);
		tv_release = (TextView) findViewById(R.id.tv_release);
		tv_now_weather = (TextView) findViewById(R.id.tv_now_weather);
		tv_today_temp = (TextView) findViewById(R.id.tv_today_temp);
		tv_now_temp = (TextView) findViewById(R.id.tv_now_temp);
		tv_aqi = (TextView) findViewById(R.id.tv_aqi);
		tv_quality = (TextView) findViewById(R.id.tv_quality);
		tv_next_3 = (TextView) findViewById(R.id.tv_next_3);
		tv_next_6 = (TextView) findViewById(R.id.tv_next_6);
		tv_next_9 = (TextView) findViewById(R.id.tv_next_9);
		tv_next_12 = (TextView) findViewById(R.id.tv_next_12);
		tv_next_15 = (TextView) findViewById(R.id.tv_next_15);
		tv_next_3_tmp = (TextView) findViewById(R.id.tv_next_3_tmp);
		tv_next_6_tmp = (TextView) findViewById(R.id.tv_next_6_tmp);
		tv_next_9_tmp = (TextView) findViewById(R.id.tv_next_9_tmp);
		tv_next_12_tmp = (TextView) findViewById(R.id.tv_next_12_tmp);
		tv_next_15_tmp = (TextView) findViewById(R.id.tv_next_15_tmp);
		tv_today_temp_a = (TextView) findViewById(R.id.tv_today_temp_a);
		tv_today_temp_b = (TextView) findViewById(R.id.tv_today_temp_b);
		tv_tommorrow = (TextView) findViewById(R.id.tv_tommorrow);
		tv_tommorrow_temp_a = (TextView) findViewById(R.id.tv_tommorrow_temp_a);
		tv_tommorrow_temp_b = (TextView) findViewById(R.id.tv_tommorrow_temp_b);
		tv_3rd_day = (TextView) findViewById(R.id.tv_3rd_day);
		tv_3rd_temp_a = (TextView) findViewById(R.id.tv_3rd_temp_a);
		tv_3rd_temp_b = (TextView) findViewById(R.id.tv_3rd_temp_b);
		tv_4th_day = (TextView) findViewById(R.id.tv_4th_day);
		tv_4th_temp_a = (TextView) findViewById(R.id.tv_4th_temp_a);
		tv_4th_temp_b = (TextView) findViewById(R.id.tv_4th_temp_b);
		tv_felt_air_temp = (TextView) findViewById(R.id.tv_felt_air_temp);
		tv_humidity = (TextView) findViewById(R.id.tv_humidity);
		tv_wind = (TextView) findViewById(R.id.tv_wind);
		tv_uv_index = (TextView) findViewById(R.id.tv_uv_index);
		tv_dressing_index  = (TextView) findViewById(R.id.tv_dressing_index);

		iv_now_weather = (ImageView) findViewById(R.id.iv_now_weather);
		iv_next_3 = (ImageView) findViewById(R.id.iv_next_3);
		iv_next_6 = (ImageView) findViewById(R.id.iv_next_6);
		iv_next_9 = (ImageView) findViewById(R.id.iv_next_9);
		iv_next_12 = (ImageView) findViewById(R.id.iv_next_12);
		iv_next_15 = (ImageView) findViewById(R.id.iv_next_15);
		iv_today_weather = (ImageView) findViewById(R.id.iv_today_weather);
		iv_tommorrow_weather = (ImageView) findViewById(R.id.iv_tommorrow_weather);
		iv_3rd_weather = (ImageView) findViewById(R.id.iv_3rd_weather);
		iv_4th_weather = (ImageView) findViewById(R.id.iv_4th_weather);
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (requestCode ==1 && resultCode == 1) {
			String city = data.getStringExtra("city");
			mService.getCityWeather(city);
		}
	}

	@Override
	protected void onDestroy() {
		unbindService(conn);
		super.onDestroy();
	}
}


text:
#ifndef WIN_PTHREADS
#define WIN_PTHREADS

#include <windows.h>
#include <setjmp.h>
#include <errno.h>
#include <sys/timeb.h>

#define ETIMEDOUT	110
#define ENOTSUP		134

#define PTHREAD_CANCEL_DISABLE 0
#define PTHREAD_CANCEL_ENABLE 0x01

#define PTHREAD_CANCEL_DEFERRED 0
#define PTHREAD_CANCEL_ASYNCHRONOUS 0x02

#define PTHREAD_CREATE_JOINABLE 0
#define PTHREAD_CREATE_DETACHED 0x04

#define PTHREAD_EXPLICT_SCHED 0
#define PTHREAD_INHERIT_SCHED 0x08

#define PTHREAD_SCOPE_PROCESS 0
#define PTHREAD_SCOPE_SYSTEM 0x10

#define PTHREAD_DEFAULT_ATTR (PTHREAD_CANCEL_ENABLE)

#define PTHREAD_CANCELED ((void *) 0xDEADBEEF)

#define PTHREAD_ONCE_INIT 0
#define PTHREAD_MUTEX_INITIALIZER {(void*)-1,-1,0,0,0,0}
#define PTHREAD_RWLOCK_INITIALIZER {0}
#define PTHREAD_COND_INITIALIZER {0}
#define PTHREAD_BARRIER_INITIALIZER \
	{0,0,PTHREAD_MUTEX_INITIALIZER,PTHREAD_COND_INITIALIZER}
#define PTHREAD_SPINLOCK_INITIALIZER 0

#define PTHREAD_DESTRUCTOR_ITERATIONS 256
#define PTHREAD_KEYS_MAX (1<<20)

#define PTHREAD_MUTEX_NORMAL 0
#define PTHREAD_MUTEX_ERRORCHECK 1
#define PTHREAD_MUTEX_RECURSIVE 2
#define PTHREAD_MUTEX_DEFAULT 3
#define PTHREAD_MUTEX_SHARED 4
#define PTHREAD_MUTEX_PRIVATE 0
#define PTHREAD_PRIO_NONE 0
#define PTHREAD_PRIO_INHERIT 8
#define PTHREAD_PRIO_PROTECT 16
#define PTHREAD_PRIO_MULT 32
#define PTHREAD_PROCESS_SHARED 0
#define PTHREAD_PROCESS_PRIVATE 1

#define PTHREAD_BARRIER_SERIAL_THREAD 1

/* Windows doesn't have this, so declare it ourselves. */
struct timespec
{
	/* long long in windows is the same as long in unix for 64bit */
	long long tv_sec;
	long long tv_nsec;
};

typedef struct _pthread_cleanup _pthread_cleanup;
struct _pthread_cleanup
{
	void (*func)(void *);
	void *arg;
	_pthread_cleanup *next;
};

struct _pthread_v
{
	void *ret_arg;
	void *(* func)(void *);
	_pthread_cleanup *clean;
	HANDLE h;
	int cancelled;
	unsigned p_state;
	int keymax;
	void **keyval;

	jmp_buf jb;
};

typedef struct _pthread_v *pthread_t;

typedef struct pthread_barrier_t pthread_barrier_t;
struct pthread_barrier_t
{
	int count;
	int total;
	CRITICAL_SECTION m;
	CONDITION_VARIABLE cv;
};

typedef struct pthread_attr_t pthread_attr_t;
struct pthread_attr_t
{
	unsigned p_state;
	void *stack;
	size_t s_size;
};

typedef long pthread_once_t;
typedef unsigned pthread_mutexattr_t;
typedef SRWLOCK pthread_rwlock_t;
typedef CRITICAL_SECTION pthread_mutex_t;
typedef unsigned pthread_key_t;
typedef void *pthread_barrierattr_t;
typedef long pthread_spinlock_t;
typedef int pthread_condattr_t;
typedef CONDITION_VARIABLE pthread_cond_t;
typedef int pthread_rwlockattr_t;

volatile long _pthread_cancelling;

int _pthread_concur;

/* Will default to zero as needed */
pthread_once_t _pthread_tls_once;
DWORD _pthread_tls;

/* Note initializer is zero, so this works */
pthread_rwlock_t _pthread_key_lock;
long _pthread_key_max;
long _pthread_key_sch;
void (**_pthread_key_dest)(void *);

#define pthread_cleanup_push(F, A)\
{\
	const _pthread_cleanup _pthread_cup = {(F), (A), pthread_self()->clean};\
	_ReadWriteBarrier();\
	pthread_self()->clean = (_pthread_cleanup *) &_pthread_cup;\
	_ReadWriteBarrier()

/* Note that if async cancelling is used, then there is a race here */
#define pthread_cleanup_pop(E)\
	(pthread_self()->clean = _pthread_cup.next, (E?_pthread_cup.func(_pthread_cup.arg):0));}

static void _pthread_once_cleanup(pthread_once_t *o)
{
	*o = 0;
}

static pthread_t pthread_self(void);
static int pthread_once(pthread_once_t *o, void (*func)(void))
{
	long state = *o;

	_ReadWriteBarrier();

	while (state != 1)
	{
		if (!state)
		{
			if (!_InterlockedCompareExchange(o, 2, 0))
			{
				/* Success */
				pthread_cleanup_push(_pthread_once_cleanup, o);
				func();
				pthread_cleanup_pop(0);

				/* Mark as done */
				*o = 1;

				return 0;
			}
		}

		YieldProcessor();

		_ReadWriteBarrier();

		state = *o;
	}

	/* Done */
	return 0;

}

static int _pthread_once_raw(pthread_once_t *o, void (*func)(void))
{
	long state = *o;

	_ReadWriteBarrier();

	while (state != 1)
	{
		if (!state)
		{
			if (!_InterlockedCompareExchange(o, 2, 0))
			{
				/* Success */
				func();

				/* Mark as done */
				*o = 1;

				return 0;
			}
		}

		YieldProcessor();

		_ReadWriteBarrier();

		state = *o;
	}

	/* Done */
	return 0;
}

static int pthread_mutex_lock(pthread_mutex_t *m)
{
	EnterCriticalSection(m);
	return 0;
}

static int pthread_mutex_unlock(pthread_mutex_t *m)
{
	LeaveCriticalSection(m);
	return 0;
}

static int pthread_mutex_trylock(pthread_mutex_t *m)
{
	return TryEnterCriticalSection(m) ? 0 : EBUSY;
}

static int pthread_mutex_init(pthread_mutex_t *m, pthread_mutexattr_t *a)
{
	(void) a;
	InitializeCriticalSection(m);

	return 0;
}

static int pthread_mutex_destroy(pthread_mutex_t *m)
{
	DeleteCriticalSection(m);
	return 0;
}

#define pthread_mutex_getprioceiling(M, P) ENOTSUP
#define pthread_mutex_setprioceiling(M, P) ENOTSUP

static int pthread_equal(pthread_t t1, pthread_t t2)
{
	return t1 == t2;
}

static void pthread_testcancel(void);

static int pthread_rwlock_init(pthread_rwlock_t *l, pthread_rwlockattr_t *a)
{
	(void) a;
	InitializeSRWLock(l);

	return 0;
}

static int pthread_rwlock_destroy(pthread_rwlock_t *l)
{
	(void) *l;
	return 0;
}

static int pthread_rwlock_rdlock(pthread_rwlock_t *l)
{
	pthread_testcancel();
	AcquireSRWLockShared(l);

	return 0;
}

static int pthread_rwlock_wrlock(pthread_rwlock_t *l)
{
	pthread_testcancel();
	AcquireSRWLockExclusive(l);

	return 0;
}

static void pthread_tls_init(void)
{
	_pthread_tls = TlsAlloc();

	/* Cannot continue if out of indexes */
	if (_pthread_tls == TLS_OUT_OF_INDEXES) abort();
}

static void _pthread_cleanup_dest(pthread_t t)
{
	int i, j;

	for (j = 0; j < PTHREAD_DESTRUCTOR_ITERATIONS; j++)
	{
		int flag = 0;

		for (i = 0; i < t->keymax; i++)
		{
			void *val = t->keyval[i];

			if (val)
			{
				pthread_rwlock_rdlock(&_pthread_key_lock);
				if ((uintptr_t) _pthread_key_dest[i] > 1)
				{
					/* Call destructor */
					t->keyval[i] = NULL;
					_pthread_key_dest[i](val);
					flag = 1;
				}
				pthread_rwlock_unlock(&_pthread_key_lock);
			}
		}

		/* Nothing to do? */
		if (!flag) return;
	}
}

static pthread_t pthread_self(void)
{
	pthread_t t;

	_pthread_once_raw(&_pthread_tls_once, pthread_tls_init);

	t = TlsGetValue(_pthread_tls);

	/* Main thread? */
	if (!t)
	{
		t = malloc(sizeof(struct _pthread_v));

		/* If cannot initialize main thread, then the only thing we can do is abort */
		if (!t) abort();

		t->ret_arg = NULL;
		t->func = NULL;
		t->clean = NULL;
		t->cancelled = 0;
		t->p_state = PTHREAD_DEFAULT_ATTR;
		t->keymax = 0;
		t->keyval = NULL;
		t->h = GetCurrentThread();

		/* Save for later */
		TlsSetValue(_pthread_tls, t);

		if (setjmp(t->jb))
		{
			/* Make sure we free ourselves if we are detached */
			if (!t->h) free(t);

			/* Time to die */
			_endthreadex(0);
		}
	}

	return t;
}

static int pthread_rwlock_unlock(pthread_rwlock_t *l)
{
	void *state = *(void **)l;

	if (state == (void *) 1)
	{
		/* Known to be an exclusive lock */
		ReleaseSRWLockExclusive(l);
	}
	else
	{
		/* A shared unlock will work */
		ReleaseSRWLockShared(l);
	}

	return 0;
}

static int pthread_rwlock_tryrdlock(pthread_rwlock_t *l)
{
	/* Get the current state of the lock */
	void *state = *(void **) l;

	if (!state)
	{
		/* Unlocked to locked */
		if (!_InterlockedCompareExchangePointer((void *) l, (void *)0x11, NULL)) return 0;
		return EBUSY;
	}

	/* A single writer exists */
	if (state == (void *) 1) return EBUSY;

	/* Multiple writers exist? */
	if ((uintptr_t) state & 14) return EBUSY;

	if (_InterlockedCompareExchangePointer((void *) l, (void *) ((uintptr_t)state + 16), state) == state) return 0;

	return EBUSY;
}

static int pthread_rwlock_trywrlock(pthread_rwlock_t *l)
{
	/* Try to grab lock if it has no users */
	if (!_InterlockedCompareExchangePointer((void *) l, (void *)1, NULL)) return 0;

	return EBUSY;
}

static unsigned long long _pthread_time_in_ms(void)
{
	struct __timeb64 tb;

	_ftime64(&tb);

	return tb.time * 1000 + tb.millitm;
}

static unsigned long long _pthread_time_in_ms_from_timespec(const struct timespec *ts)
{
	unsigned long long t = ts->tv_sec * 1000;
	t += ts->tv_nsec / 1000000;

	return t;
}

static unsigned long long _pthread_rel_time_in_ms(const struct timespec *ts)
{
	unsigned long long t1 = _pthread_time_in_ms_from_timespec(ts);
	unsigned long long t2 = _pthread_time_in_ms();

	/* Prevent underflow */
	if (t1 < t2) return 1;
	return t1 - t2;
}

static int pthread_rwlock_timedrdlock(pthread_rwlock_t *l, const struct timespec *ts)
{
	unsigned long long ct = _pthread_time_in_ms();
	unsigned long long t = _pthread_time_in_ms_from_timespec(ts);

	pthread_testcancel();

	/* Use a busy-loop */
	while (1)
	{
		/* Try to grab lock */
		if (!pthread_rwlock_tryrdlock(l)) return 0;

		/* Get current time */
		ct = _pthread_time_in_ms();

		/* Have we waited long enough? */
		if (ct > t) return ETIMEDOUT;
	}
}

static int pthread_rwlock_timedwrlock(pthread_rwlock_t *l, const struct timespec *ts)
{
	unsigned long long ct = _pthread_time_in_ms();
	unsigned long long t = _pthread_time_in_ms_from_timespec(ts);

	pthread_testcancel();

	/* Use a busy-loop */
	while (1)
	{
		/* Try to grab lock */
		if (!pthread_rwlock_trywrlock(l)) return 0;

		/* Get current time */
		ct = _pthread_time_in_ms();

		/* Have we waited long enough? */
		if (ct > t) return ETIMEDOUT;
	}
}

static int pthread_get_concurrency(int *val)
{
	*val = _pthread_concur;
	return 0;
}

static int pthread_set_concurrency(int val)
{
	_pthread_concur = val;
	return 0;
}

#define pthread_getschedparam(T, P, S) ENOTSUP
#define pthread_setschedparam(T, P, S) ENOTSUP
#define pthread_getcpuclockid(T, C) ENOTSUP

static int pthread_exit(void *res)
{
	pthread_t t = pthread_self();

	t->ret_arg = res;

	_pthread_cleanup_dest(t);

	longjmp(t->jb, 1);
}

static void _pthread_invoke_cancel(void)
{
	_pthread_cleanup *pcup;

	_InterlockedDecrement(&_pthread_cancelling);

	/* Call cancel queue */
	for (pcup = pthread_self()->clean; pcup; pcup = pcup->next)
	{
		pcup->func(pcup->arg);
	}

	pthread_exit(PTHREAD_CANCELED);
}

static void pthread_testcancel(void)
{
	if (_pthread_cancelling)
	{
		pthread_t t = pthread_self();

		if (t->cancelled && (t->p_state & PTHREAD_CANCEL_ENABLE))
		{
			_pthread_invoke_cancel();
		}
	}
}

static int pthread_cancel(pthread_t t)
{
	if (t->p_state & PTHREAD_CANCEL_ASYNCHRONOUS)
	{
		/* Dangerous asynchronous cancelling */
		CONTEXT ctxt;

		/* Already done? */
		if (t->cancelled) return ESRCH;

		ctxt.ContextFlags = CONTEXT_CONTROL;

		SuspendThread(t->h);
		GetThreadContext(t->h, &ctxt);
#ifdef _M_X64
		ctxt.Rip = (uintptr_t) _pthread_invoke_cancel;
#else
		ctxt.Eip = (uintptr_t) _pthread_invoke_cancel;
#endif
		SetThreadContext(t->h, &ctxt);

		/* Also try deferred Cancelling */
		t->cancelled = 1;

		/* Notify everyone to look */
		_InterlockedIncrement(&_pthread_cancelling);

		ResumeThread(t->h);
	}
	else
	{
		/* Safe deferred Cancelling */
		t->cancelled = 1;

		/* Notify everyone to look */
		_InterlockedIncrement(&_pthread_cancelling);
	}

	return 0;
}

static unsigned _pthread_get_state(pthread_attr_t *attr, unsigned flag)
{
	return attr->p_state & flag;
}

static int _pthread_set_state(pthread_attr_t *attr, unsigned flag, unsigned val)
{
	if (~flag & val) return EINVAL;
	attr->p_state &= ~flag;
	attr->p_state |= val;

	return 0;
}

static int pthread_attr_init(pthread_attr_t *attr)
{
	attr->p_state = PTHREAD_DEFAULT_ATTR;
	attr->stack = NULL;
	attr->s_size = 0;
	return 0;
}

static int pthread_attr_destroy(pthread_attr_t *attr)
{
	/* No need to do anything */
	return 0;
}

static int pthread_attr_setdetachstate(pthread_attr_t *a, int flag)
{
	return _pthread_set_state(a, PTHREAD_CREATE_DETACHED, flag);
}

static int pthread_attr_getdetachstate(pthread_attr_t *a, int *flag)
{
	*flag = _pthread_get_state(a, PTHREAD_CREATE_DETACHED);
	return 0;
}

static int pthread_attr_setinheritsched(pthread_attr_t *a, int flag)
{
	return _pthread_set_state(a, PTHREAD_INHERIT_SCHED, flag);
}

static int pthread_attr_getinheritsched(pthread_attr_t *a, int *flag)
{
	*flag = _pthread_get_state(a, PTHREAD_INHERIT_SCHED);
	return 0;
}

static int pthread_attr_setscope(pthread_attr_t *a, int flag)
{
	return _pthread_set_state(a, PTHREAD_SCOPE_SYSTEM, flag);
}

static int pthread_attr_getscope(pthread_attr_t *a, int *flag)
{
	*flag = _pthread_get_state(a, PTHREAD_SCOPE_SYSTEM);
	return 0;
}

static int pthread_attr_getstackaddr(pthread_attr_t *attr, void **stack)
{
	*stack = attr->stack;
	return 0;
}

static int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stack)
{
	attr->stack = stack;
	return 0;
}

static int pthread_attr_getstacksize(pthread_attr_t *attr, size_t *size)
{
	*size = attr->s_size;
	return 0;
}

static int pthread_attr_setstacksize(pthread_attr_t *attr, size_t size)
{
	attr->s_size = size;
	return 0;
}

#define pthread_attr_getguardsize(A, S) ENOTSUP
#define pthread_attr_setgaurdsize(A, S) ENOTSUP
#define pthread_attr_getschedparam(A, S) ENOTSUP
#define pthread_attr_setschedparam(A, S) ENOTSUP
#define pthread_attr_getschedpolicy(A, S) ENOTSUP
#define pthread_attr_setschedpolicy(A, S) ENOTSUP

static int pthread_setcancelstate(int state, int *oldstate)
{
	pthread_t t = pthread_self();

	if ((state & PTHREAD_CANCEL_ENABLE) != state) return EINVAL;
	if (oldstate) *oldstate = t->p_state & PTHREAD_CANCEL_ENABLE;
	t->p_state &= ~PTHREAD_CANCEL_ENABLE;
	t->p_state |= state;

	return 0;
}

static int pthread_setcanceltype(int type, int *oldtype)
{
	pthread_t t = pthread_self();

	if ((type & PTHREAD_CANCEL_ASYNCHRONOUS) != type) return EINVAL;
	if (oldtype) *oldtype = t->p_state & PTHREAD_CANCEL_ASYNCHRONOUS;
	t->p_state &= ~PTHREAD_CANCEL_ASYNCHRONOUS;
	t->p_state |= type;

	return 0;
}

static int pthread_create_wrapper(void *args)
{
	struct _pthread_v *tv = args;
	int i, j;

	_pthread_once_raw(&_pthread_tls_once, pthread_tls_init);

	TlsSetValue(_pthread_tls, tv);

	if (!setjmp(tv->jb))
	{
		/* Call function and save return value */
		tv->ret_arg = tv->func(tv->ret_arg);

		/* Clean up destructors */
		_pthread_cleanup_dest(tv);
	}

	/* If we exit too early, then we can race with create */
	while (tv->h == (HANDLE) -1)
	{
		YieldProcessor();
		_ReadWriteBarrier();
	}

	/* Make sure we free ourselves if we are detached */
	if (!tv->h) free(tv);

	return 0;
}

static int pthread_create(pthread_t *th, pthread_attr_t *attr, void *(* func)(void *), void *arg)
{
	struct _pthread_v *tv = malloc(sizeof(struct _pthread_v));
	unsigned ssize = 0;

	if (!tv) return 1;

	*th = tv;

	/* Save data in pthread_t */
	tv->ret_arg = arg;
	tv->func = func;
	tv->clean = NULL;
	tv->cancelled = 0;
	tv->p_state = PTHREAD_DEFAULT_ATTR;
	tv->keymax = 0;
	tv->keyval = NULL;
	tv->h = (HANDLE) -1;

	if (attr)
	{
		tv->p_state = attr->p_state;
		ssize = attr->s_size;
	}

	/* Make sure tv->h has value of -1 */
	_ReadWriteBarrier();

	tv->h = (HANDLE) _beginthreadex(NULL, ssize, pthread_create_wrapper, tv, 0, NULL);

	/* Failed */
	if (!tv->h) return 1;

	if (tv->p_state & PTHREAD_CREATE_DETACHED)
	{
		CloseHandle(tv->h);
		_ReadWriteBarrier();
		tv->h = 0;
	}

	return 0;
}

static int pthread_join(pthread_t t, void **res)
{
	struct _pthread_v *tv = t;

	pthread_testcancel();

	WaitForSingleObject(tv->h, INFINITE);
	CloseHandle(tv->h);

	/* Obtain return value */
	if (res) *res = tv->ret_arg;

	free(tv);

	return 0;
}

static int pthread_detach(pthread_t t)
{
	struct _pthread_v *tv = t;

	/*
	 * This can't race with thread exit because
	 * our call would be undefined if called on a dead thread.
	 */

	CloseHandle(tv->h);
	_ReadWriteBarrier();
	tv->h = 0;

	return 0;
}

static int pthread_mutexattr_init(pthread_mutexattr_t *a)
{
	*a = 0;
	return 0;
}

static int pthread_mutexattr_destroy(pthread_mutexattr_t *a)
{
	(void) a;
	return 0;
}

static int pthread_mutexattr_gettype(pthread_mutexattr_t *a, int *type)
{
	*type = *a & 3;

	return 0;
}

static int pthread_mutexattr_settype(pthread_mutexattr_t *a, int type)
{
	if ((unsigned) type > 3) return EINVAL;
	*a &= ~3;
	*a |= type;

	return 0;
}

static int pthread_mutexattr_getpshared(pthread_mutexattr_t *a, int *type)
{
	*type = *a & 4;

	return 0;
}

static int pthread_mutexattr_setpshared(pthread_mutexattr_t * a, int type)
{
	if ((type & 4) != type) return EINVAL;

	*a &= ~4;
	*a |= type;

	return 0;
}

static int pthread_mutexattr_getprotocol(pthread_mutexattr_t *a, int *type)
{
	*type = *a & (8 + 16);

	return 0;
}

static int pthread_mutexattr_setprotocol(pthread_mutexattr_t *a, int type)
{
	if ((type & (8 + 16)) != 8 + 16) return EINVAL;

	*a &= ~(8 + 16);
	*a |= type;

	return 0;
}

static int pthread_mutexattr_getprioceiling(pthread_mutexattr_t *a, int * prio)
{
	*prio = *a / PTHREAD_PRIO_MULT;
	return 0;
}

static int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *a, int prio)
{
	*a &= (PTHREAD_PRIO_MULT - 1);
	*a += prio * PTHREAD_PRIO_MULT;

	return 0;
}

static int pthread_mutex_timedlock(pthread_mutex_t *m, struct timespec *ts)
{
	unsigned long long t, ct;

	struct _pthread_crit_t
	{
		void *debug;
		LONG count;
		LONG r_count;
		HANDLE owner;
		HANDLE sem;
		ULONG_PTR spin;
	};

	/* Try to lock it without waiting */
	if (!pthread_mutex_trylock(m)) return 0;

	ct = _pthread_time_in_ms();
	t = _pthread_time_in_ms_from_timespec(ts);

	while (1)
	{
		/* Have we waited long enough? */
		if (ct > t) return ETIMEDOUT;

		/* Wait on semaphore within critical section */
		WaitForSingleObject(((struct _pthread_crit_t *)m)->sem, t - ct);

		/* Try to grab lock */
		if (!pthread_mutex_trylock(m)) return 0;

		/* Get current time */
		ct = _pthread_time_in_ms();
	}
}

static int pthread_barrier_destroy(pthread_barrier_t *b)
{
	DeleteCriticalSection(&b->m);

	return 0;

}

static int pthread_barrier_init(pthread_barrier_t *b, void *attr, int count)
{
	/* Ignore attr */
	(void) attr;

	InitializeCriticalSection(&b->m);
	InitializeConditionVariable(&b->cv);
	b->count = count;
	b->total = 0;

	return 0;
}

#define _PTHREAD_BARRIER_FLAG (1<<30)
static int pthread_barrier_wait(pthread_barrier_t *b)
{
	EnterCriticalSection(&b->m);

	while (b->total > _PTHREAD_BARRIER_FLAG)
	{
		/* Wait until everyone exits the barrier */
		SleepConditionVariableCS(&b->cv, &b->m, INFINITE);
	}

	/* Are we the first to enter? */
	if (b->total == _PTHREAD_BARRIER_FLAG) b->total = 0;

	b->total++;

	if (b->total == b->count)
	{
		b->total += _PTHREAD_BARRIER_FLAG - 1;
		WakeAllConditionVariable(&b->cv);

		LeaveCriticalSection(&b->m);

		return 1;
	}
	else
	{
		while (b->total < _PTHREAD_BARRIER_FLAG)
		{
			/* Wait until enough threads enter the barrier */
			SleepConditionVariableCS(&b->cv, &b->m, INFINITE);
		}

		b->total--;

		/* Get entering threads to wake up */
		if (b->total == _PTHREAD_BARRIER_FLAG) WakeAllConditionVariable(&b->cv);

		LeaveCriticalSection(&b->m);

		return 0;
	}
}

static int pthread_barrierattr_init(void **attr)
{
	*attr = NULL;
	return 0;
}

static int pthread_barrierattr_destroy(void **attr)
{
	/* Ignore attr */
	(void) attr;

	return 0;
}

static int pthread_barrierattr_setpshared(void **attr, int s)
{
	*attr = (void *) s;
	return 0;
}

static int pthread_barrierattr_getpshared(void **attr, int *s)
{
	*s = (int) (size_t) *attr;

	return 0;
}

static int pthread_key_create(pthread_key_t *key, void (* dest)(void *))
{
	int i;
	long nmax;
	void (**d)(void *);

	if (!key) return EINVAL;

	pthread_rwlock_wrlock(&_pthread_key_lock);

	for (i = _pthread_key_sch; i < _pthread_key_max; i++)
	{
		if (!_pthread_key_dest[i])
		{
			*key = i;
			if (dest)
			{
				_pthread_key_dest[i] = dest;
			}
			else
			{
				_pthread_key_dest[i] = (void(*)(void *))1;
			}
			pthread_rwlock_unlock(&_pthread_key_lock);

			return 0;
		}
	}

	for (i = 0; i < _pthread_key_sch; i++)
	{
		if (!_pthread_key_dest[i])
		{
			*key = i;
			if (dest)
			{
				_pthread_key_dest[i] = dest;
			}
			else
			{
				_pthread_key_dest[i] = (void(*)(void *))1;
			}
			pthread_rwlock_unlock(&_pthread_key_lock);

			return 0;
		}
	}

	if (!_pthread_key_max) _pthread_key_max = 1;
	if (_pthread_key_max == PTHREAD_KEYS_MAX)
	{
		pthread_rwlock_unlock(&_pthread_key_lock);

		return ENOMEM;
	}

	nmax = _pthread_key_max * 2;
	if (nmax > PTHREAD_KEYS_MAX) nmax = PTHREAD_KEYS_MAX;

	/* No spare room anywhere */
	d = realloc(_pthread_key_dest, nmax * sizeof(*d));
	if (!d)
	{
		pthread_rwlock_unlock(&_pthread_key_lock);

		return ENOMEM;
	}

	/* Clear new region */
	memset((void *) &d[_pthread_key_max], 0, (nmax-_pthread_key_max)*sizeof(void *));

	/* Use new region */
	_pthread_key_dest = d;
	_pthread_key_sch = _pthread_key_max + 1;
	*key = _pthread_key_max;
	_pthread_key_max = nmax;

	if (dest)
	{
		_pthread_key_dest[*key] = dest;
	}
	else
	{
		_pthread_key_dest[*key] = (void(*)(void *))1;
	}

	pthread_rwlock_unlock(&_pthread_key_lock);

	return 0;
}

static int pthread_key_delete(pthread_key_t key)
{
	if (key > _pthread_key_max) return EINVAL;
	if (!_pthread_key_dest) return EINVAL;

	pthread_rwlock_wrlock(&_pthread_key_lock);
	_pthread_key_dest[key] = NULL;

	/* Start next search from our location */
	if (_pthread_key_sch > key) _pthread_key_sch = key;

	pthread_rwlock_unlock(&_pthread_key_lock);

	return 0;
}

static void *pthread_getspecific(pthread_key_t key)
{
	pthread_t t = pthread_self();

	if (key >= t->keymax) return NULL;

	return t->keyval[key];

}

static int pthread_setspecific(pthread_key_t key, const void *value)
{
	pthread_t t = pthread_self();

	if (key > t->keymax)
	{
		int keymax = (key + 1) * 2;
		void **kv = realloc(t->keyval, keymax * sizeof(void *));

		if (!kv) return ENOMEM;

		/* Clear new region */
		memset(&kv[t->keymax], 0, (keymax - t->keymax)*sizeof(void*));

		t->keyval = kv;
		t->keymax = keymax;
	}

	t->keyval[key] = (void *) value;

	return 0;
}

static int pthread_spin_init(pthread_spinlock_t *l, int pshared)
{
	(void) pshared;

	*l = 0;
	return 0;
}

static int pthread_spin_destroy(pthread_spinlock_t *l)
{
	(void) l;
	return 0;
}

/* No-fair spinlock due to lack of knowledge of thread number */
static int pthread_spin_lock(pthread_spinlock_t *l)
{
	while (_InterlockedExchange(l, EBUSY))
	{
		/* Don't lock the bus whilst waiting */
		while (*l)
		{
			YieldProcessor();

			/* Compiler barrier.  Prevent caching of *l */
			_ReadWriteBarrier();
		}
	}

	return 0;
}

static int pthread_spin_trylock(pthread_spinlock_t *l)
{
	return _InterlockedExchange(l, EBUSY);
}

static int pthread_spin_unlock(pthread_spinlock_t *l)
{
	/* Compiler barrier.  The store below acts with release symmantics */
	_ReadWriteBarrier();

	*l = 0;

	return 0;
}

static int pthread_cond_init(pthread_cond_t *c, pthread_condattr_t *a)
{
	(void) a;

	InitializeConditionVariable(c);
	return 0;
}

static int pthread_cond_signal(pthread_cond_t *c)
{
	WakeConditionVariable(c);
	return 0;
}

static int pthread_cond_broadcast(pthread_cond_t *c)
{
	WakeAllConditionVariable(c);
	return 0;
}

static int pthread_cond_wait(pthread_cond_t *c, pthread_mutex_t *m)
{
	pthread_testcancel();
	SleepConditionVariableCS(c, m, INFINITE);
	return 0;
}

static int pthread_cond_destroy(pthread_cond_t *c)
{
	(void) c;
	return 0;
}

static int pthread_cond_timedwait(pthread_cond_t *c, pthread_mutex_t *m, struct timespec *t)
{
	unsigned long long tm = _pthread_rel_time_in_ms(t);

	pthread_testcancel();

	if (!SleepConditionVariableCS(c, m, tm)) return ETIMEDOUT;

	/* We can have a spurious wakeup after the timeout */
	if (!_pthread_rel_time_in_ms(t)) return ETIMEDOUT;

	return 0;
}

static int pthread_condattr_destroy(pthread_condattr_t *a)
{
	(void) a;
	return 0;
}

#define pthread_condattr_getclock(A, C) ENOTSUP
#define pthread_condattr_setclock(A, C) ENOTSUP

static int pthread_condattr_init(pthread_condattr_t *a)
{
	*a = 0;
	return 0;
}

static int pthread_condattr_getpshared(pthread_condattr_t *a, int *s)
{
	*s = *a;
	return 0;
}

static int pthread_condattr_setpshared(pthread_condattr_t *a, int s)
{
	*a = s;
	return 0;
}

static int pthread_rwlockattr_destroy(pthread_rwlockattr_t *a)
{
	(void) a;
	return 0;
}

static int pthread_rwlockattr_init(pthread_rwlockattr_t *a)
{
	*a = 0;
}

static int pthread_rwlockattr_getpshared(pthread_rwlockattr_t *a, int *s)
{
	*s = *a;
	return 0;
}

static int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *a, int s)
{
	*a = s;
	return 0;
}

/* No fork() in windows - so ignore this */
#define pthread_atfork(F1,F2,F3) 0

/* Windows has rudimentary signals support */
#define pthread_kill(T, S) 0
#define pthread_sigmask(H, S1, S2) 0

/* Wrap cancellation points */
#define accept(...) (pthread_testcancel(), accept(__VA_ARGS__))
#define aio_suspend(...) (pthread_testcancel(), aio_suspend(__VA_ARGS__))
#define clock_nanosleep(...) (pthread_testcancel(), clock_nanosleep(__VA_ARGS__))
#define close(...) (pthread_testcancel(), close(__VA_ARGS__))
#define connect(...) (pthread_testcancel(), connect(__VA_ARGS__))
#define creat(...) (pthread_testcancel(), creat(__VA_ARGS__))
#define fcntl(...) (pthread_testcancel(), fcntl(__VA_ARGS__))
#define fdatasync(...) (pthread_testcancel(), fdatasync(__VA_ARGS__))
#define fsync(...) (pthread_testcancel(), fsync(__VA_ARGS__))
#define getmsg(...) (pthread_testcancel(), getmsg(__VA_ARGS__))
#define getpmsg(...) (pthread_testcancel(), getpmsg(__VA_ARGS__))
#define lockf(...) (pthread_testcancel(), lockf(__VA_ARGS__))
#define mg_receive(...) (pthread_testcancel(), mg_receive(__VA_ARGS__))
#define mg_send(...) (pthread_testcancel(), mg_send(__VA_ARGS__))
#define mg_timedreceive(...) (pthread_testcancel(), mg_timedreceive(__VA_ARGS__))
#define mg_timessend(...) (pthread_testcancel(), mg_timedsend(__VA_ARGS__))
#define msgrcv(...) (pthread_testcancel(), msgrecv(__VA_ARGS__))
#define msgsnd(...) (pthread_testcancel(), msgsnd(__VA_ARGS__))
#define msync(...) (pthread_testcancel(), msync(__VA_ARGS__))
#define nanosleep(...) (pthread_testcancel(), nanosleep(__VA_ARGS__))
#define open(...) (pthread_testcancel(), open(__VA_ARGS__))
#define pause(...) (pthread_testcancel(), pause(__VA_ARGS__))
#define poll(...) (pthread_testcancel(), poll(__VA_ARGS__))
#define pread(...) (pthread_testcancel(), pread(__VA_ARGS__))
#define pselect(...) (pthread_testcancel(), pselect(__VA_ARGS__))
#define putmsg(...) (pthread_testcancel(), putmsg(__VA_ARGS__))
#define putpmsg(...) (pthread_testcancel(), putpmsg(__VA_ARGS__))
#define pwrite(...) (pthread_testcancel(), pwrite(__VA_ARGS__))
#define read(...) (pthread_testcancel(), read(__VA_ARGS__))
#define readv(...) (pthread_testcancel(), readv(__VA_ARGS__))
#define recv(...) (pthread_testcancel(), recv(__VA_ARGS__))
#define recvfrom(...) (pthread_testcancel(), recvfrom(__VA_ARGS__))
#define recvmsg(...) (pthread_testcancel(), recvmsg(__VA_ARGS__))
#define select(...) (pthread_testcancel(), select(__VA_ARGS__))
#define sem_timedwait(...) (pthread_testcancel(), sem_timedwait(__VA_ARGS__))
#define sem_wait(...) (pthread_testcancel(), sem_wait(__VA_ARGS__))
#define send(...) (pthread_testcancel(), send(__VA_ARGS__))
#define sendmsg(...) (pthread_testcancel(), sendmsg(__VA_ARGS__))
#define sendto(...) (pthread_testcancel(), sendto(__VA_ARGS__))
#define sigpause(...) (pthread_testcancel(), sigpause(__VA_ARGS__))
#define sigsuspend(...) (pthread_testcancel(), sigsuspend(__VA_ARGS__))
#define sigwait(...) (pthread_testcancel(), sigwait(__VA_ARGS__))
#define sigwaitinfo(...) (pthread_testcancel(), sigwaitinfo(__VA_ARGS__))
#define sleep(...) (pthread_testcancel(), sleep(__VA_ARGS__))
//#define Sleep(...) (pthread_testcancel(), Sleep(__VA_ARGS__))
#define system(...) (pthread_testcancel(), system(__VA_ARGS__))

#define access(...) (pthread_testcancel(), access(__VA_ARGS__))
#define asctime(...) (pthread_testcancel(), asctime(__VA_ARGS__))
#define asctime_r(...) (pthread_testcancel(), asctime_r(__VA_ARGS__))
#define catclose(...) (pthread_testcancel(), catclose(__VA_ARGS__))
#define catgets(...) (pthread_testcancel(), catgets(__VA_ARGS__))
#define catopen(...) (pthread_testcancel(), catopen(__VA_ARGS__))
#define closedir(...) (pthread_testcancel(), closedir(__VA_ARGS__))
#define closelog(...) (pthread_testcancel(), closelog(__VA_ARGS__))
#define ctermid(...) (pthread_testcancel(), ctermid(__VA_ARGS__))
#define ctime(...) (pthread_testcancel(), ctime(__VA_ARGS__))
#define ctime_r(...) (pthread_testcancel(), ctime_r(__VA_ARGS__))
#define dbm_close(...) (pthread_testcancel(), dbm_close(__VA_ARGS__))
#define dbm_delete(...) (pthread_testcancel(), dbm_delete(__VA_ARGS__))
#define dbm_fetch(...) (pthread_testcancel(), dbm_fetch(__VA_ARGS__))
#define dbm_nextkey(...) (pthread_testcancel(), dbm_nextkey(__VA_ARGS__))
#define dbm_open(...) (pthread_testcancel(), dbm_open(__VA_ARGS__))
#define dbm_store(...) (pthread_testcancel(), dbm_store(__VA_ARGS__))
#define dlclose(...) (pthread_testcancel(), dlclose(__VA_ARGS__))
#define dlopen(...) (pthread_testcancel(), dlopen(__VA_ARGS__))
#define endgrent(...) (pthread_testcancel(), endgrent(__VA_ARGS__))
#define endhostent(...) (pthread_testcancel(), endhostent(__VA_ARGS__))
#define endnetent(...) (pthread_testcancel(), endnetent(__VA_ARGS__))
#define endprotoent(...) (pthread_testcancel(), endprotoend(__VA_ARGS__))
#define endpwent(...) (pthread_testcancel(), endpwent(__VA_ARGS__))
#define endservent(...) (pthread_testcancel(), endservent(__VA_ARGS__))
#define endutxent(...) (pthread_testcancel(), endutxent(__VA_ARGS__))
#define fclose(...) (pthread_testcancel(), fclose(__VA_ARGS__))
#define fflush(...) (pthread_testcancel(), fflush(__VA_ARGS__))
#define fgetc(...) (pthread_testcancel(), fgetc(__VA_ARGS__))
#define fgetpos(...) (pthread_testcancel(), fgetpos(__VA_ARGS__))
#define fgets(...) (pthread_testcancel(), fgets(__VA_ARGS__))
#define fgetwc(...) (pthread_testcancel(), fgetwc(__VA_ARGS__))
#define fgetws(...) (pthread_testcancel(), fgetws(__VA_ARGS__))
#define fmtmsg(...) (pthread_testcancel(), fmtmsg(__VA_ARGS__))
#define fopen(...) (pthread_testcancel(), fopen(__VA_ARGS__))
#define fpathconf(...) (pthread_testcancel(), fpathconf(__VA_ARGS__))
#define fprintf(...) (pthread_testcancel(), fprintf(__VA_ARGS__))
#define fputc(...) (pthread_testcancel(), fputc(__VA_ARGS__))
#define fputs(...) (pthread_testcancel(), fputs(__VA_ARGS__))
#define fputwc(...) (pthread_testcancel(), fputwc(__VA_ARGS__))
#define fputws(...) (pthread_testcancel(), fputws(__VA_ARGS__))
#define fread(...) (pthread_testcancel(), fread(__VA_ARGS__))
#define freopen(...) (pthread_testcancel(), freopen(__VA_ARGS__))
#define fscanf(...) (pthread_testcancel(), fscanf(__VA_ARGS__))
#define fseek(...) (pthread_testcancel(), fseek(__VA_ARGS__))
#define fseeko(...) (pthread_testcancel(), fseeko(__VA_ARGS__))
#define fsetpos(...) (pthread_testcancel(), fsetpos(__VA_ARGS__))
#define fstat(...) (pthread_testcancel(), fstat(__VA_ARGS__))
#define ftell(...) (pthread_testcancel(), ftell(__VA_ARGS__))
#define ftello(...) (pthread_testcancel(), ftello(__VA_ARGS__))
#define ftw(...) (pthread_testcancel(), ftw(__VA_ARGS__))
#define fwprintf(...) (pthread_testcancel(), fwprintf(__VA_ARGS__))
#define fwrite(...) (pthread_testcancel(), fwrite(__VA_ARGS__))
#define fwscanf(...) (pthread_testcancel(), fwscanf(__VA_ARGS__))
#define getaddrinfo(...) (pthread_testcancel(), getaddrinfo(__VA_ARGS__))
#define getc(...) (pthread_testcancel(), getc(__VA_ARGS__))
#define getc_unlocked(...) (pthread_testcancel(), getc_unlocked(__VA_ARGS__))
#define getchar(...) (pthread_testcancel(), getchar(__VA_ARGS__))
#define getchar_unlocked(...) (pthread_testcancel(), getchar_unlocked(__VA_ARGS__))
#define getcwd(...) (pthread_testcancel(), getcwd(__VA_ARGS__))
#define getdate(...) (pthread_testcancel(), getdate(__VA_ARGS__))
#define getgrent(...) (pthread_testcancel(), getgrent(__VA_ARGS__))
#define getgrgid(...) (pthread_testcancel(), getgrgid(__VA_ARGS__))
#define getgrgid_r(...) (pthread_testcancel(), getgrgid_r(__VA_ARGS__))
#define gergrnam(...) (pthread_testcancel(), getgrnam(__VA_ARGS__))
#define getgrnam_r(...) (pthread_testcancel(), getgrnam_r(__VA_ARGS__))
#define gethostbyaddr(...) (pthread_testcancel(), gethostbyaddr(__VA_ARGS__))
#define gethostbyname(...) (pthread_testcancel(), gethostbyname(__VA_ARGS__))
#define gethostent(...) (pthread_testcancel(), gethostent(__VA_ARGS__))
#define gethostid(...) (pthread_testcancel(), gethostid(__VA_ARGS__))
#define gethostname(...) (pthread_testcancel(), gethostname(__VA_ARGS__))
#define getlogin(...) (pthread_testcancel(), getlogin(__VA_ARGS__))
#define getlogin_r(...) (pthread_testcancel(), getlogin_r(__VA_ARGS__))
#define getnameinfo(...) (pthread_testcancel(), getnameinfo(__VA_ARGS__))
#define getnetbyaddr(...) (pthread_testcancel(), getnetbyaddr(__VA_ARGS__))
#define getnetbyname(...) (pthread_testcancel(), getnetbyname(__VA_ARGS__))
#define getnetent(...) (pthread_testcancel(), getnetent(__VA_ARGS__))
#define getopt(...) (pthread_testcancel(), getopt(__VA_ARGS__))
#define getprotobyname(...) (pthread_testcancel(), getprotobyname(__VA_ARGS__))
#define getprotobynumber(...) (pthread_testcancel(), getprotobynumber(__VA_ARGS__))
#define getprotoent(...) (pthread_testcancel(), getprotoent(__VA_ARGS__))
#define getpwent(...) (pthread_testcancel(), getpwent(__VA_ARGS__))
#define getpwnam(...) (pthread_testcancel(), getpwnam(__VA_ARGS__))
#define getpwnam_r(...) (pthread_testcancel(), getpwnam_r(__VA_ARGS__))
#define getpwuid(...) (pthread_testcancel(), getpwuid(__VA_ARGS__))
#define getpwuid_r(...) (pthread_testcancel(), getpwuid_r(__VA_ARGS__))
#define gets(...) (pthread_testcancel(), gets(__VA_ARGS__))
#define getservbyname(...) (pthread_testcancel(), getservbyname(__VA_ARGS__))
#define getservbyport(...) (pthread_testcancel(), getservbyport(__VA_ARGS__))
#define getservent(...) (pthread_testcancel(), getservent(__VA_ARGS__))
#define getutxent(...) (pthread_testcancel(), getutxent(__VA_ARGS__))
#define getutxid(...) (pthread_testcancel(), getutxid(__VA_ARGS__))
#define getutxline(...) (pthread_testcancel(), getutxline(__VA_ARGS__))
#undef getwc
#define getwc(...) (pthread_testcancel(), getwc(__VA_ARGS__))
#undef getwchar
#define getwchar(...) (pthread_testcancel(), getwcahr(__VA_ARGS__))
#define getwd(...) (pthread_testcancel(), getwd(__VA_ARGS__))
#define glob(...) (pthread_testcancel(), glob(__VA_ARGS__))
#define iconv_close(...) (pthread_testcancel(), iconv_close(__VA_ARGS__))
#define iconv_open(...) (pthread_testcancel(), iconv_open(__VA_ARGS__))
#define ioctl(...) (pthread_testcancel(), ioctl(__VA_ARGS__))
#define link(...) (pthread_testcancel(), link(__VA_ARGS__))
#define localtime(...) (pthread_testcancel(), localtime(__VA_ARGS__))
#define localtime_r(...) (pthread_testcancel(), localtime_r(__VA_ARGS__))
#define lseek(...) (pthread_testcancel(), lseek(__VA_ARGS__))
#define lstat(...) (pthread_testcancel(), lstat(__VA_ARGS__))
#define mkstemp(...) (pthread_testcancel(), mkstemp(__VA_ARGS__))
#define nftw(...) (pthread_testcancel(), nftw(__VA_ARGS__))
#define opendir(...) (pthread_testcancel(), opendir(__VA_ARGS__))
#define openlog(...) (pthread_testcancel(), openlog(__VA_ARGS__))
#define pathconf(...) (pthread_testcancel(), pathconf(__VA_ARGS__))
#define pclose(...) (pthread_testcancel(), pclose(__VA_ARGS__))
#define perror(...) (pthread_testcancel(), perror(__VA_ARGS__))
#define popen(...) (pthread_testcancel(), popen(__VA_ARGS__))
#define posix_fadvise(...) (pthread_testcancel(), posix_fadvise(__VA_ARGS__))
#define posix_fallocate(...) (pthread_testcancel(), posix_fallocate(__VA_ARGS__))
#define posix_madvise(...) (pthread_testcancel(), posix_madvise(__VA_ARGS__))
#define posix_openpt(...) (pthread_testcancel(), posix_openpt(__VA_ARGS__))
#define posix_spawn(...) (pthread_testcancel(), posix_spawn(__VA_ARGS__))
#define posix_spawnp(...) (pthread_testcancel(), posix_spawnp(__VA_ARGS__))
#define posix_trace_clear(...) (pthread_testcancel(), posix_trace_clear(__VA_ARGS__))
#define posix_trace_close(...) (pthread_testcancel(), posix_trace_close(__VA_ARGS__))
#define posix_trace_create(...) (pthread_testcancel(), posix_trace_create(__VA_ARGS__))
#define posix_trace_create_withlog(...) (pthread_testcancel(), posix_trace_create_withlog(__VA_ARGS__))
#define posix_trace_eventtypelist_getne(...) (pthread_testcancel(), posix_trace_eventtypelist_getne(__VA_ARGS__))
#define posix_trace_eventtypelist_rewin(...) (pthread_testcancel(), posix_trace_eventtypelist_rewin(__VA_ARGS__))
#define posix_trace_flush(...) (pthread_testcancel(), posix_trace_flush(__VA_ARGS__))
#define posix_trace_get_attr(...) (pthread_testcancel(), posix_trace_get_attr(__VA_ARGS__))
#define posix_trace_get_filter(...) (pthread_testcancel(), posix_trace_get_filter(__VA_ARGS__))
#define posix_trace_get_status(...) (pthread_testcancel(), posix_trace_get_status(__VA_ARGS__))
#define posix_trace_getnext_event(...) (pthread_testcancel(), posix_trace_getnext_event(__VA_ARGS__))
#define posix_trace_open(...) (pthread_testcancel(), posix_trace_open(__VA_ARGS__))
#define posix_trace_rewind(...) (pthread_testcancel(), posix_trace_rewind(__VA_ARGS__))
#define posix_trace_setfilter(...) (pthread_testcancel(), posix_trace_setfilter(__VA_ARGS__))
#define posix_trace_shutdown(...) (pthread_testcancel(), posix_trace_shutdown(__VA_ARGS__))
#define posix_trace_timedgetnext_event(...) (pthread_testcancel(), posix_trace_timedgetnext_event(__VA_ARGS__))
#define posix_typed_mem_open(...) (pthread_testcancel(), posix_typed_mem_open(__VA_ARGS__))
#define printf(...) (pthread_testcancel(), printf(__VA_ARGS__))
#define putc(...) (pthread_testcancel(), putc(__VA_ARGS__))
#define putc_unlocked(...) (pthread_testcancel(), putc_unlocked(__VA_ARGS__))
#define putchar(...) (pthread_testcancel(), putchar(__VA_ARGS__))
#define putchar_unlocked(...) (pthread_testcancel(), putchar_unlocked(__VA_ARGS__))
#define puts(...) (pthread_testcancel(), puts(__VA_ARGS__))
#define pututxline(...) (pthread_testcancel(), pututxline(__VA_ARGS__))
#undef putwc
#define putwc(...) (pthread_testcancel(), putwc(__VA_ARGS__))
#undef putwchar
#define putwchar(...) (pthread_testcancel(), putwchar(__VA_ARGS__))
#define readdir(...) (pthread_testcancel(), readdir(__VA_ARSG__))
#define readdir_r(...) (pthread_testcancel(), readdir_r(__VA_ARGS__))
#define remove(...) (pthread_testcancel(), remove(__VA_ARGS__))
#define rename(...) (pthread_testcancel(), rename(__VA_ARGS__))
#define rewind(...) (pthread_testcancel(), rewind(__VA_ARGS__))
#define rewinddir(...) (pthread_testcancel(), rewinddir(__VA_ARGS__))
#define scanf(...) (pthread_testcancel(), scanf(__VA_ARGS__))
#define seekdir(...) (pthread_testcancel(), seekdir(__VA_ARGS__))
#define semop(...) (pthread_testcancel(), semop(__VA_ARGS__))
#define setgrent(...) (pthread_testcancel(), setgrent(__VA_ARGS__))
#define sethostent(...) (pthread_testcancel(), sethostemt(__VA_ARGS__))
#define setnetent(...) (pthread_testcancel(), setnetent(__VA_ARGS__))
#define setprotoent(...) (pthread_testcancel(), setprotoent(__VA_ARGS__))
#define setpwent(...) (pthread_testcancel(), setpwent(__VA_ARGS__))
#define setservent(...) (pthread_testcancel(), setservent(__VA_ARGS__))
#define setutxent(...) (pthread_testcancel(), setutxent(__VA_ARGS__))
#define stat(...) (pthread_testcancel(), stat(__VA_ARGS__))
#define strerror(...) (pthread_testcancel(), strerror(__VA_ARGS__))
#define strerror_r(...) (pthread_testcancel(), strerror_r(__VA_ARGS__))
#define strftime(...) (pthread_testcancel(), strftime(__VA_ARGS__))
#define symlink(...) (pthread_testcancel(), symlink(__VA_ARGS__))
#define sync(...) (pthread_testcancel(), sync(__VA_ARGS__))
#define syslog(...) (pthread_testcancel(), syslog(__VA_ARGS__))
#define tmpfile(...) (pthread_testcancel(), tmpfile(__VA_ARGS__))
#define tmpnam(...) (pthread_testcancel(), tmpnam(__VA_ARGS__))
#define ttyname(...) (pthread_testcancel(), ttyname(__VA_ARGS__))
#define ttyname_r(...) (pthread_testcancel(), ttyname_r(__VA_ARGS__))
#define tzset(...) (pthread_testcancel(), tzset(__VA_ARGS__))
#define ungetc(...) (pthread_testcancel(), ungetc(__VA_ARGS__))
#define ungetwc(...) (pthread_testcancel(), ungetwc(__VA_ARGS__))
#define unlink(...) (pthread_testcancel(), unlink(__VA_ARGS__))
#define vfprintf(...) (pthread_testcancel(), vfprintf(__VA_ARGS__))
#define vfwprintf(...) (pthread_testcancel(), vfwprintf(__VA_ARGS__))
#define vprintf(...) (pthread_testcancel(), vprintf(__VA_ARGS__))
#define vwprintf(...) (pthread_testcancel(), vwprintf(__VA_ARGS__))
#define wcsftime(...) (pthread_testcancel(), wcsftime(__VA_ARGS__))
#define wordexp(...) (pthread_testcancel(), wordexp(__VA_ARGS__))
#define wprintf(...) (pthread_testcancel(), wprintf(__VA_ARGS__))
#define wscanf(...) (pthread_testcancel(), wscanf(__VA_ARGS__))

#endif /* WIN_PTHREADS */