init
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
Some checks failed
Docker. / Ubuntu (push) Has been cancelled
User-agent updater. / User-agent (push) Failing after 15s
Lock Threads / lock (push) Failing after 10s
Waiting for answer. / waiting-for-answer (push) Failing after 22s
Needs user action. / needs-user-action (push) Failing after 8s
Can't reproduce. / cant-reproduce (push) Failing after 8s
Close stale issues and PRs / stale (push) Has been cancelled
This commit is contained in:
31
Telegram/ThirdParty/dispatch/.gitignore
vendored
Normal file
31
Telegram/ThirdParty/dispatch/.gitignore
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
# Mac OS X filesystem metadata
|
||||
.DS_Store
|
||||
|
||||
# Xcode user artifacts
|
||||
xcuserdata
|
||||
project.xcworkspace
|
||||
|
||||
# python generated files
|
||||
*.pyc
|
||||
|
||||
# build files generated by the configure script
|
||||
*.ninja
|
||||
.ninja_deps
|
||||
.ninja_log
|
||||
|
||||
Build
|
||||
.build
|
||||
|
||||
# build files generated by autotools
|
||||
Makefile
|
||||
Makefile.in
|
||||
config.log
|
||||
configure
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
config.log
|
||||
config.status
|
||||
config
|
||||
configure
|
||||
libtool
|
||||
.dirstamp
|
||||
0
Telegram/ThirdParty/dispatch/.gitmodules
vendored
Normal file
0
Telegram/ThirdParty/dispatch/.gitmodules
vendored
Normal file
134
Telegram/ThirdParty/dispatch/.mailmap
vendored
Normal file
134
Telegram/ThirdParty/dispatch/.mailmap
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
Adrian-Constantin Popescu <epsilon.gamma@gmail.com> <adrian-constantin.popescu@outlook.com>
|
||||
Alex Blewitt <alblue@apple.com> <alex.blewitt@gmail.com>
|
||||
Alex Hoppen <alex@alexhoppen.de> <alex@ateamer.de>
|
||||
Alexis Beingessner <abeingessner@apple.com> <a.beingessner@gmail.com>
|
||||
Alper Çugun <github@alper.nl> <alper@users.noreply.github.com>
|
||||
Amr Aboelela <amraboelela@gmail.com> <amraboelela@users.noreply.github.com>
|
||||
Ankit Aggarwal <ankit_aggarwal@apple.com> <ankit.spd@gmail.com>
|
||||
Argyrios Kyrtzidis <kyrtzidis@apple.com> <akyrtzi@gmail.com>
|
||||
Arsen Gasparyan <to.arsen.gasparyan@gmail.com> <frootloops@users.noreply.github.com>
|
||||
Ben Cohen <ben_cohen@apple.com>
|
||||
Ben Cohen <ben_cohen@apple.com> <airspeedswift@users.noreply.github.com>
|
||||
Ben Cohen <ben_cohen@apple.com> <ben@airspeedvelocity.net>
|
||||
Ben Langmuir <blangmuir@apple.com> <ben.langmuir@gmail.com>
|
||||
Brent Royal-Gordon <brent@brentdax.com> <brent@architechies.com>
|
||||
Brian Croom <bcroom@apple.com> <brian.s.croom@gmail.com>
|
||||
Brian Gesiak <bgesiak@fb.com> <modocache@gmail.com>
|
||||
Bryan Chan <bryan.chan@ca.ibm.com> <bryanpkc@gmail.com>
|
||||
Calvin Hill <mr_j.c.h@hotmail.com> <return@users.noreply.github.com>
|
||||
Chris Bieneman <beanz@apple.com>
|
||||
Chris Bieneman <beanz@apple.com> <cbieneman@apple.com>
|
||||
Chris Lattner <clattner@nondot.org> <clattner@apple.com>
|
||||
Chris Lattner <clattner@nondot.org> <lattner@users.noreply.github.com>
|
||||
Chris Lattner <clattner@nondot.org> <sabre@iMac.local>
|
||||
Chris Williams <cwilliams@fitbit.com> <ultramiraculous@users.noreply.github.com>
|
||||
codester <sahil.profile@gmail.com> codestergit <sahil.profile@gmail.com>
|
||||
Dan Liew <dliew@apple.com> <36706441+danliew-apple@users.noreply.github.com>
|
||||
Daniel Duan <daniel@duan.org> <danmarner@gmail.com>
|
||||
Dante Broggi <34220985+Dante-Broggi@users.noreply.github.com>
|
||||
Dave <davesweeris@mac.com>
|
||||
Dave Abrahams <dabrahams@apple.com> <dave@boostpro.com>
|
||||
Dave Abrahams <dabrahams@apple.com> <dave@fripp.apple.com>
|
||||
Dave Abrahams <dabrahams@apple.com> <dave@Skree.local>
|
||||
Dave Abrahams <dabrahams@apple.com> <dave@Wingy.local>
|
||||
Dave Lee <davelee@lyft.com> <davelee.com@gmail.com>
|
||||
David Rönnqvist <david.ronnqvist@gmail.com> <david.ronnqvist@skype.net>
|
||||
David Zarzycki <dave@znu.io> <zarzycki@icloud.com>
|
||||
David Zarzycki <dave@znu.io> <zarzycki@mac.com>
|
||||
Davide Italiano <ditaliano@apple.com> <dcci@users.noreply.github.com>
|
||||
Davide Italiano <ditaliano@apple.com> <dccitaliano@gmail.com>
|
||||
Dmitri Gribenko <gribozavr@gmail.com> <dgribenko@apple.com>
|
||||
Doug Coleman <doug_coleman@apple.com> <doug.coleman@gmail.com>
|
||||
Enrico Granata <egranata@apple.com> <egranata@egranata.apple.com>
|
||||
Enrico Granata <egranata@apple.com> <granata.enrico@gmail.com>
|
||||
Erik Eckstein <eeckstein@apple.com> <eeckstein@apple.com>
|
||||
Erik Eckstein <eeckstein@apple.com> <eeckstein@rad-main.corp.apple.com>
|
||||
Erik Verbruggen <erik.verbruggen@me.com> <erikjv@users.noreply.github.com>
|
||||
Ewa Matejska <ematejska@apple.com> <ematejska@apple.com>
|
||||
Ewa Matejska <ematejska@apple.com> <ematejska@Ewas-MacBook-Pro.local>
|
||||
Ewa Matejska <ematejska@apple.com> <ewamatejska@Ewas-iMac.local>
|
||||
Florent Bruneau <florent.bruneau@intersec.com> <florent.bruneau_github@m4x.org>
|
||||
Francis Ricci <fjricci@fb.com> <francisjricci@gmail.com>
|
||||
GauravDS <er.gauravds@gmail.com> <gaurav.sharma@punchh.com>
|
||||
Graydon Hoare <ghoare@apple.com> <graydon@users.noreply.github.com>
|
||||
Greg Parker <gparker@apple.com> <gparker-github@sealiesoftware.com>
|
||||
Guillaume Lessard <dhtnstff@gmail.com> <glessard@users.noreply.github.com>
|
||||
Hamish <hamish2knight@gmail.com> <hamish2knight@gmail.com>
|
||||
Han Sangjin <tinysun@jssolution.co.kr> <tinysun.net@gmail.com>
|
||||
Harlan Haskins <harlan@apple.com> <harlan@harlanhaskins.com>
|
||||
Hitster GTD <hitstergtd@users.noreply.github.com> <hitstergtd@users.noreply.github.com>
|
||||
Huon Wilson <huon@apple.com> <dbau.pp+github@gmail.com>
|
||||
Ingmar Stein <IngmarStein@users.noreply.github.com>
|
||||
Itai Ferber <iferber@apple.com> <itai@itaiferber.net>
|
||||
Jacob Bandes-Storch <jacob@bandes-stor.ch> <jacob@bandes-storch.net>
|
||||
Jacob Mizraji <jmizraji@apple.com> <jacobmizraji@gmail.com>
|
||||
Janosch Hildebrand <jnosh@jnosh.com> <jnosh+git@jnosh.com>
|
||||
Janosch Hildebrand <jnosh@jnosh.com> <jnosh+github@jnosh.com>
|
||||
Javier Soto <jsbustos@twitch.tv> <javier.api@gmail.com>
|
||||
Javier Soto <jsbustos@twitch.tv> <javiers@twitter.com>
|
||||
Joe <joe@iachieved.it>
|
||||
Joe <joewillsher@icloud.com>
|
||||
joe DeCapo <joe@polka.cat>
|
||||
Joe Groff <jgroff@apple.com> <arcata@gmail.com>
|
||||
Joe Shajrawi <shajrawi@apple.com> <joeshajrawi@iMac-2.local>
|
||||
Joe Shajrawi <shajrawi@apple.com> <joeshajrawi@Joes-iMac-Pro.local>
|
||||
Johannes Weiß <johannesweiss@apple.com> <github@tux4u.de>
|
||||
John Regner <john@johnregner.com> <regnerjr@gmail.com>
|
||||
Karoy Lorentey <klorentey@apple.com> <karoly@lorentey.hu>
|
||||
Keith Smiley <k@keith.so> <keithbsmiley@gmail.com>
|
||||
Kevin Ballard <kevin@sb.org> <kevin.ballard@postmates.com>
|
||||
Kosuke Ogawa <ogawa_kousuke@aratana.jp> <koogawa.app@gmail.com>
|
||||
Kuba Mracek <mracek@apple.com> <jbrecka@apple.com>
|
||||
Luiz Fernando Silva <luizinho_mack@yahoo.com.br>
|
||||
Luqman Aden <luqman@apple.com> <luqman_aden@apple.com>
|
||||
Marcelo Fabri <me@marcelofabri.com> <marcelofabri@users.noreply.github.com>
|
||||
Mark Lacey <mark.lacey@apple.com> <rudkx@icloud.com>
|
||||
Mark Lacey <mark.lacey@apple.com> <rudkx@users.noreply.github.com>
|
||||
Matt Rajca <matt.rajca@me.com> <mattrajca@users.noreply.github.com>
|
||||
Max Moiseev <moiseev@apple.com> <maxim.moiseev@gmail.com>
|
||||
Max Moiseev <moiseev@apple.com> <moiseev@users.noreply.github.com>
|
||||
Maxwell Swadling <maxs@apple.com> <maxwellswadling@gmail.com>
|
||||
Maxwell Swadling <maxs@apple.com> <mswadling@apple.com>
|
||||
Mayur Raiturkar <mayur@mayur.xyz> <mayurkr@users.noreply.github.com>
|
||||
Michael Gottesman <mgottesman@apple.com> <gottesmm@users.noreply.github.com>
|
||||
Michael Ilseman <milseman@apple.com> <michael.ilseman@gmail.com>
|
||||
Mike Ash <mikeash@apple.com> <mike@mikeash.com>
|
||||
Mike Ferris <mferris@apple.com> <mike@lorax.com>
|
||||
Mishal Awadah <mawadah@apple.com>
|
||||
Mishal Shah <mishal_shah@apple.com> <shahmishal@users.noreply.github.com>
|
||||
Nadav Rotem <nrotem@apple.com> <nadavrot@users.noreply.github.com>
|
||||
Nate Cook <natecook@apple.com> <nate@Nates-MacBook-Pro.local>
|
||||
Nate Cook <natecook@apple.com> <natecook@gmail.com>
|
||||
Nate Cook <natecook@apple.com> <natecook1000@users.noreply.github.com>
|
||||
Nate Cook <natecook@apple.com> <nmersethcook@apple.com>
|
||||
Nathan Lanza <lanza@fb.com> <nathan@lanza.io>
|
||||
Nicole Jacque <jacque@apple.com>
|
||||
Niels Andriesse <andriesseniels@gmail.com> <nielsandriesse@users.noreply.github.com>
|
||||
Paul Meng <mno2@mno2.org> <mno2.csie@gmail.com>
|
||||
Pavel Yaskevich <pyaskevich@apple.com> <xedin@apache.org>
|
||||
Paweł Szot <pszot@pgs-soft.com>
|
||||
Paweł Szot <pszot@pgs-soft.com> <qwertyszot@gmail.com>
|
||||
Pete Cooper <peter_cooper@apple.com>
|
||||
Philip Ridgeway <pridgeway@vernier.com> <philip.ridgeway@gmail.com>
|
||||
Richard Wei <rxwei@apple.com> <rxwei@google.com>
|
||||
Rintaro Ishizaki <rishizaki@apple.com> <fs.output@gmail.com>
|
||||
Robert Widmann <rwidmann@apple.com> <devteam.codafi@gmail.com>
|
||||
Roman Levenstein <rlevenstein@apple.com> <swiftix@users.noreply.github.com>
|
||||
Ross Bayer <ross.m.bayer@gmail.com> <Rostepher@users.noreply.github.com>
|
||||
Russ Bishop <rbishopjr@apple.com> <russ@plangrid.com>
|
||||
Ryan Lovelett <ryan@lovelett.me> <RLovelett@users.noreply.github.com>
|
||||
Shawn Erickson <shawn.erickson@citrix.com> <shawnce@gmail.com>
|
||||
Slava Pestov <spestov@apple.com> <spestov@rad-main.corp.apple.com>
|
||||
Slava Pestov <spestov@apple.com> <sviatoslav.pestov@gmail.com>
|
||||
Stephen Canon <scanon@apple.com>
|
||||
Stephen Canon <scanon@apple.com> <stephentyrone@gmail.com>
|
||||
Sukolsak Sakshuwong <sukolsak@gmail.com>
|
||||
Todd Fiala <tfiala@apple.com> <todd.fiala@gmail.com>
|
||||
Toni Suter <tonisuter@me.com> <tonisuter@users.noreply.github.com>
|
||||
Vedant Kumar <vsk@apple.com> <vk@vedantk.com>
|
||||
Xi Ge <xi_ge@apple.com> <xi_ge@rad-main.corp.apple.com>
|
||||
Xin Tong <xin_tong@apple.com> <trent.xin.tong@gmail.com>
|
||||
Xin Tong <xin_tong@apple.com> <trentxintong@Xins-MacBook-Pro.local>
|
||||
Yuka Ezura <ezura@users.noreply.github.com> <2020337+ezura@users.noreply.github.com>
|
||||
Yurii Samsoniuk <ura@google.com> <mr.sigito@gmail.com>
|
||||
Zac Bowling <zbowling@google.com> <zac@zacbowling.com>
|
||||
352
Telegram/ThirdParty/dispatch/CMakeLists.txt
vendored
Normal file
352
Telegram/ThirdParty/dispatch/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,352 @@
|
||||
|
||||
cmake_minimum_required(VERSION 3.15.1)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
|
||||
|
||||
# NOTE(compnerd) enable CMP0091 - select MSVC runtime based on
|
||||
# CMAKE_MSVC_RUNTIME_LIBRARY. Requires CMake 3.15 or newer.
|
||||
if(POLICY CMP0091)
|
||||
cmake_policy(SET CMP0091 NEW)
|
||||
endif()
|
||||
|
||||
project(dispatch
|
||||
VERSION 1.3
|
||||
LANGUAGES C CXX)
|
||||
|
||||
if("${CMAKE_C_SIMULATE_ID}" STREQUAL "MSVC")
|
||||
include(ClangClCompileRules)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL Windows)
|
||||
if(NOT MINGW)
|
||||
include(DispatchWindowsSupport)
|
||||
dispatch_windows_arch_spelling(${CMAKE_SYSTEM_PROCESSOR} DISPATCH_MSVC_ARCH)
|
||||
dispatch_windows_include_for_arch(${DISPATCH_MSVC_ARCH} DISPATCH_INCLUDES)
|
||||
include_directories(BEFORE SYSTEM ${DISPATCH_INCLUDES})
|
||||
dispatch_windows_lib_for_arch(${CMAKE_SYSTEM_PROCESSOR} DISPATCH_LIBDIR)
|
||||
link_directories(${DISPATCH_LIBDIR})
|
||||
endif()
|
||||
|
||||
include(CheckCSourceCompiles)
|
||||
include(CheckSymbolExists)
|
||||
|
||||
check_c_source_compiles([=[
|
||||
#include <Windows.h>
|
||||
int main(int argc, char *argv[]) {
|
||||
switch ((LOGICAL_PROCESSOR_RELATIONSHIP)0) {
|
||||
case RelationProcessorDie:
|
||||
case RelationNumaNodeEx:
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
]=] DISPATCH_HAVE_EXTENDED_SLPI_20348)
|
||||
if(DISPATCH_HAVE_EXTENDED_SLPI_20348)
|
||||
add_compile_definitions(DISPATCH_HAVE_EXTENDED_SLPI_20348)
|
||||
endif()
|
||||
|
||||
check_c_source_compiles([=[
|
||||
#include <Windows.h>
|
||||
int main(int argc, char *argv[]) {
|
||||
switch ((LOGICAL_PROCESSOR_RELATIONSHIP)0) {
|
||||
case RelationProcessorModule:
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
]=] DISPATCH_HAVE_EXTENDED_SLPI_22000)
|
||||
if(DISPATCH_HAVE_EXTENDED_SLPI_22000)
|
||||
add_compile_definitions(DISPATCH_HAVE_EXTENDED_SLPI_22000)
|
||||
endif()
|
||||
|
||||
check_c_source_compiles([=[
|
||||
#include <Windows.h>
|
||||
#include <winternl.h>
|
||||
int main(int argc, char *argv[]) {
|
||||
FILE_PIPE_LOCAL_INFORMATION fpli;
|
||||
}
|
||||
]=] HAVE_FILE_PIPE_LOCAL_INFORMATION)
|
||||
if(HAVE_FILE_PIPE_LOCAL_INFORMATION)
|
||||
add_compile_definitions(HAVE_FILE_PIPE_LOCAL_INFORMATION)
|
||||
endif()
|
||||
|
||||
check_symbol_exists(mkstemp "stdlib.h" HAVE_MKSTEMP)
|
||||
if(HAVE_MKSTEMP)
|
||||
add_compile_definitions(HAVE_MKSTEMP)
|
||||
endif()
|
||||
|
||||
check_c_source_compiles([=[
|
||||
#include <sys/types.h>
|
||||
int main(int argc, char *argv[]) {
|
||||
mode_t mode;
|
||||
}
|
||||
]=] HAVE_MODE_T)
|
||||
if(HAVE_MODE_T)
|
||||
add_compile_definitions(HAVE_MODE_T)
|
||||
endif()
|
||||
|
||||
check_c_source_compiles([=[
|
||||
#include <sys/types.h>
|
||||
int main(int argc, char *argv[]) {
|
||||
pid_t mode;
|
||||
}
|
||||
]=] HAVE_PID_T)
|
||||
if(HAVE_PID_T)
|
||||
add_compile_definitions(HAVE_PID_T)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_STANDARD_REQUIRED YES)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
|
||||
set(CMAKE_C_VISIBILITY_PRESET hidden)
|
||||
set(CMAKE_C_VISIBILITY_INLINES_HIDDEN YES)
|
||||
|
||||
# NOTE(compnerd) this is a horrible workaround for Windows to ensure that the
|
||||
# tests can run as there is no rpath equivalent and `PATH` is used to lookup the
|
||||
# libraries.
|
||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
|
||||
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
|
||||
if(ANDROID)
|
||||
set(CMAKE_HAVE_LIBC_PTHREAD YES)
|
||||
endif()
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
include(CheckCCompilerFlag)
|
||||
include(CheckCSourceCompiles)
|
||||
include(CheckFunctionExists)
|
||||
include(CheckIncludeFiles)
|
||||
include(CheckLibraryExists)
|
||||
include(CheckLinkerFlag)
|
||||
include(CheckSymbolExists)
|
||||
include(GNUInstallDirs)
|
||||
include(CTest)
|
||||
|
||||
include(DispatchAppleOptions)
|
||||
include(DispatchSanitization)
|
||||
include(DispatchCompilerWarnings)
|
||||
include(DTrace)
|
||||
include(SwiftSupport)
|
||||
|
||||
# NOTE(abdulras) this is the CMake supported way to control whether we generate
|
||||
# shared or static libraries. This impacts the behaviour of `add_library` in
|
||||
# what type of library it generates.
|
||||
option(BUILD_SHARED_LIBS "build shared libraries" ON)
|
||||
|
||||
option(DISPATCH_ENABLE_ASSERTS "enable debug assertions" FALSE)
|
||||
|
||||
option(ENABLE_DISPATCH_INIT_CONSTRUCTOR "enable libdispatch_init as a constructor" ON)
|
||||
set(USE_LIBDISPATCH_INIT_CONSTRUCTOR ${ENABLE_DISPATCH_INIT_CONSTRUCTOR})
|
||||
|
||||
option(ENABLE_DTRACE "enable dtrace support" "")
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL Darwin OR CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
|
||||
set(ENABLE_INTERNAL_PTHREAD_WORKQUEUES_DEFAULT OFF)
|
||||
else()
|
||||
set(ENABLE_INTERNAL_PTHREAD_WORKQUEUES_DEFAULT ON)
|
||||
endif()
|
||||
option(ENABLE_INTERNAL_PTHREAD_WORKQUEUES "use libdispatch's own implementation of pthread workqueues" ${ENABLE_INTERNAL_PTHREAD_WORKQUEUES_DEFAULT})
|
||||
if(ENABLE_INTERNAL_PTHREAD_WORKQUEUES)
|
||||
set(DISPATCH_USE_INTERNAL_WORKQUEUE 1)
|
||||
set(HAVE_PTHREAD_WORKQUEUES 0)
|
||||
else()
|
||||
check_include_files(pthread/workqueue_private.h HAVE_PTHREAD_WORKQUEUE_PRIVATE_H)
|
||||
if(HAVE_PTHREAD_WORKQUEUE_PRIVATE_H)
|
||||
set(HAVE_PTHREAD_WORKQUEUES 1)
|
||||
set(DISPATCH_USE_INTERNAL_WORKQUEUE 0)
|
||||
else()
|
||||
set(HAVE_PTHREAD_WORKQUEUES 0)
|
||||
set(DISPATCH_USE_INTERNAL_WORKQUEUE 1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
option(INSTALL_PRIVATE_HEADERS "installs private headers in the same location as the public ones" OFF)
|
||||
|
||||
option(ENABLE_SWIFT "enable libdispatch swift overlay" OFF)
|
||||
if(ENABLE_SWIFT)
|
||||
enable_language(Swift)
|
||||
endif()
|
||||
|
||||
option(ENABLE_THREAD_LOCAL_STORAGE "enable usage of thread local storage via _Thread_local" ON)
|
||||
set(DISPATCH_USE_THREAD_LOCAL_STORAGE ${ENABLE_THREAD_LOCAL_STORAGE})
|
||||
|
||||
|
||||
check_linker_flag(C "LINKER:--build-id=sha1" LINKER_SUPPORTS_BUILD_ID)
|
||||
|
||||
check_symbol_exists(__GNU_LIBRARY__ "features.h" _GNU_SOURCE)
|
||||
if(_GNU_SOURCE)
|
||||
set(CMAKE_REQUIRED_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} -D_GNU_SOURCE)
|
||||
endif()
|
||||
|
||||
check_c_source_compiles("void __attribute__((__noreturn__)) main() { __builtin_trap(); }"
|
||||
__BUILTIN_TRAP)
|
||||
if(__BUILTIN_TRAP)
|
||||
set(HAVE_NORETURN_BUILTIN_TRAP 1)
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_SYSTEM_NAME STREQUAL Android)
|
||||
find_package(LibRT)
|
||||
endif()
|
||||
|
||||
check_function_exists(_pthread_workqueue_init HAVE__PTHREAD_WORKQUEUE_INIT)
|
||||
check_function_exists(getprogname HAVE_GETPROGNAME)
|
||||
check_function_exists(mach_absolute_time HAVE_MACH_ABSOLUTE_TIME)
|
||||
check_function_exists(mach_approximate_time HAVE_MACH_APPROXIMATE_TIME)
|
||||
check_function_exists(mach_port_construct HAVE_MACH_PORT_CONSTRUCT)
|
||||
check_function_exists(malloc_create_zone HAVE_MALLOC_CREATE_ZONE)
|
||||
check_function_exists(posix_fadvise HAVE_POSIX_FADVISE)
|
||||
check_function_exists(posix_spawnp HAVE_POSIX_SPAWNP)
|
||||
check_function_exists(pthread_key_init_np HAVE_PTHREAD_KEY_INIT_NP)
|
||||
check_function_exists(pthread_attr_setcpupercent_np HAVE_PTHREAD_ATTR_SETCPUPERCENT_NP)
|
||||
check_function_exists(pthread_yield_np HAVE_PTHREAD_YIELD_NP)
|
||||
check_function_exists(pthread_main_np HAVE_PTHREAD_MAIN_NP)
|
||||
check_function_exists(pthread_workqueue_setdispatch_np HAVE_PTHREAD_WORKQUEUE_SETDISPATCH_NP)
|
||||
check_function_exists(strlcpy HAVE_STRLCPY)
|
||||
check_function_exists(sysconf HAVE_SYSCONF)
|
||||
check_function_exists(arc4random HAVE_ARC4RANDOM)
|
||||
|
||||
check_include_files("TargetConditionals.h" HAVE_TARGETCONDITIONALS_H)
|
||||
check_include_files("dlfcn.h" HAVE_DLFCN_H)
|
||||
check_include_files("fcntl.h" HAVE_FCNTL_H)
|
||||
check_include_files("inttypes.h" HAVE_INTTYPES_H)
|
||||
check_include_files("libkern/OSAtomic.h" HAVE_LIBKERN_OSATOMIC_H)
|
||||
check_include_files("libkern/OSCrossEndian.h" HAVE_LIBKERN_OSCROSSENDIAN_H)
|
||||
check_include_files("libproc_internal.h" HAVE_LIBPROC_INTERNAL_H)
|
||||
check_include_files("mach/mach.h" HAVE_MACH)
|
||||
if(HAVE_MACH)
|
||||
set(__DARWIN_NON_CANCELABLE 1)
|
||||
else()
|
||||
set(__DARWIN_NON_CANCELABLE 0)
|
||||
endif()
|
||||
check_include_files("malloc/malloc.h" HAVE_MALLOC_MALLOC_H)
|
||||
check_include_files("memory.h" HAVE_MEMORY_H)
|
||||
check_include_files("pthread/qos.h" HAVE_PTHREAD_QOS_H)
|
||||
check_include_files("pthread/workqueue_private.h" HAVE_PTHREAD_WORKQUEUE_PRIVATE_H)
|
||||
check_include_files("pthread_machdep.h" HAVE_PTHREAD_MACHDEP_H)
|
||||
check_include_files("pthread_np.h" HAVE_PTHREAD_NP_H)
|
||||
check_include_files("pthread_workqueue.h" HAVE_PTHREAD_WORKQUEUE_H)
|
||||
check_include_files("stdint.h" HAVE_STDINT_H)
|
||||
check_include_files("stdlib.h" HAVE_STDLIB_H)
|
||||
check_include_files("string.h" HAVE_STRING_H)
|
||||
check_include_files("strings.h" HAVE_STRINGS_H)
|
||||
check_include_files("sys/guarded.h" HAVE_SYS_GUARDED_H)
|
||||
check_include_files("sys/stat.h" HAVE_SYS_STAT_H)
|
||||
check_include_files("sys/types.h" HAVE_SYS_TYPES_H)
|
||||
check_include_files("objc/objc-internal.h" HAVE_OBJC)
|
||||
|
||||
if(HAVE_MACH)
|
||||
set(USE_MACH_SEM 1)
|
||||
else()
|
||||
set(USE_MACH_SEM 0)
|
||||
endif()
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL Windows)
|
||||
add_compile_definitions($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:USE_WIN32_SEM>)
|
||||
endif()
|
||||
check_library_exists(pthread sem_init "" USE_POSIX_SEM)
|
||||
# NOTE: android has not always provided a libpthread, but uses the pthreads API
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL Android)
|
||||
set(USE_POSIX_SEM 1)
|
||||
endif()
|
||||
|
||||
check_symbol_exists(CLOCK_UPTIME "time.h" HAVE_DECL_CLOCK_UPTIME)
|
||||
check_symbol_exists(CLOCK_UPTIME_FAST "time.h" HAVE_DECL_CLOCK_UPTIME_FAST)
|
||||
check_symbol_exists(CLOCK_MONOTONIC "time.h" HAVE_DECL_CLOCK_MONOTONIC)
|
||||
check_symbol_exists(CLOCK_REALTIME "time.h" HAVE_DECL_CLOCK_REALTIME)
|
||||
check_symbol_exists(CLOCK_MONOTONIC_COARSE "time.h" HAVE_DECL_CLOCK_MONOTONIC_COARSE)
|
||||
check_symbol_exists(FD_COPY "sys/select.h" HAVE_DECL_FD_COPY)
|
||||
check_symbol_exists(NOTE_LOWAT "sys/event.h" HAVE_DECL_NOTE_LOWAT)
|
||||
check_symbol_exists(NOTE_NONE "sys/event.h" HAVE_DECL_NOTE_NONE)
|
||||
check_symbol_exists(NOTE_REAP "sys/event.h" HAVE_DECL_NOTE_REAP)
|
||||
check_symbol_exists(NOTE_REVOKE "sys/event.h" HAVE_DECL_NOTE_REVOKE)
|
||||
check_symbol_exists(NOTE_SIGNAL "sys/event.h" HAVE_DECL_NOTE_SIGNAL)
|
||||
check_symbol_exists(POSIX_SPAWN_START_SUSPENDED "sys/spawn.h" HAVE_DECL_POSIX_SPAWN_START_SUSPENDED)
|
||||
check_symbol_exists(SIGEMT "signal.h" HAVE_DECL_SIGEMT)
|
||||
check_symbol_exists(VQ_DESIRED_DISK "sys/mount.h" HAVE_DECL_VQ_DESIRED_DISK)
|
||||
check_symbol_exists(VQ_NEARLOWDISK "sys/mount.h" HAVE_DECL_VQ_NEARLOWDISK)
|
||||
check_symbol_exists(VQ_QUOTA "sys/mount.h" HAVE_DECL_VQ_QUOTA)
|
||||
check_symbol_exists(VQ_UPDATE "sys/mount.h" HAVE_DECL_VQ_UPDATE)
|
||||
check_symbol_exists(VQ_VERYLOWDISK "sys/mount.h" HAVE_DECL_VQ_VERYLOWDISK)
|
||||
check_symbol_exists(VQ_FREE_SPACE_CHANGE "sys/mount.h" HAVE_DECL_VQ_FREE_SPACE_CHANGE)
|
||||
check_symbol_exists(strlcpy "string.h" HAVE_STRLCPY)
|
||||
check_symbol_exists(program_invocation_name "errno.h" HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME)
|
||||
if (HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME)
|
||||
add_compile_definitions($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:_GNU_SOURCE=1>)
|
||||
endif()
|
||||
check_symbol_exists(__printflike "bsd/sys/cdefs.h" HAVE_PRINTFLIKE)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL Android)
|
||||
set(ENABLE_DTRACE_DEFAULT OFF)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL FreeBSD)
|
||||
add_compile_definitions($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:_WITH_DPRINTF>)
|
||||
endif()
|
||||
|
||||
if(ENABLE_DTRACE)
|
||||
find_program(dtrace_EXECUTABLE dtrace)
|
||||
if(NOT dtrace_EXECUTABLE AND NOT ENABLE_DTRACE STREQUAL "")
|
||||
message(FATAL_ERROR "dtrace not found but explicitly requested")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(dtrace_EXECUTABLE)
|
||||
add_compile_definitions($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:DISPATCH_USE_DTRACE=1>)
|
||||
else()
|
||||
add_compile_definitions($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:DISPATCH_USE_DTRACE=0>)
|
||||
endif()
|
||||
|
||||
find_program(leaks_EXECUTABLE leaks)
|
||||
if(leaks_EXECUTABLE)
|
||||
set(HAVE_LEAKS TRUE)
|
||||
endif()
|
||||
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-fmodule-map-file=${PROJECT_SOURCE_DIR}/dispatch/darwin/module.modulemap>
|
||||
$<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-fmodule-map-file=${PROJECT_SOURCE_DIR}/private/darwin/module.modulemap>)
|
||||
else()
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-fmodule-map-file=${PROJECT_SOURCE_DIR}/dispatch/generic/module.modulemap>
|
||||
$<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-fmodule-map-file=${PROJECT_SOURCE_DIR}/private/generic/module.modulemap>)
|
||||
endif()
|
||||
|
||||
configure_file("${PROJECT_SOURCE_DIR}/cmake/config.h.in"
|
||||
"${PROJECT_BINARY_DIR}/config/config_ac.h")
|
||||
add_compile_definitions($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:HAVE_CONFIG_H>)
|
||||
|
||||
|
||||
if(ENABLE_SWIFT)
|
||||
if(NOT SWIFT_SYSTEM_NAME)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
|
||||
set(SWIFT_SYSTEM_NAME macosx)
|
||||
else()
|
||||
set(SWIFT_SYSTEM_NAME "$<LOWER_CASE:${CMAKE_SYSTEM_NAME}>")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(INSTALL_TARGET_DIR "${CMAKE_INSTALL_LIBDIR}/swift$<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:_static>/${SWIFT_SYSTEM_NAME}" CACHE PATH "Path where the libraries will be installed")
|
||||
set(INSTALL_DISPATCH_HEADERS_DIR "${CMAKE_INSTALL_LIBDIR}/swift$<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:_static>/dispatch" CACHE PATH "Path where the headers will be installed for libdispatch")
|
||||
set(INSTALL_BLOCK_HEADERS_DIR "${CMAKE_INSTALL_LIBDIR}/swift$<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:_static>/Block" CACHE PATH "Path where the headers will be installed for the blocks runtime")
|
||||
set(INSTALL_OS_HEADERS_DIR "${CMAKE_INSTALL_LIBDIR}/swift$<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:_static>/os" CACHE PATH "Path where the os/ headers will be installed")
|
||||
else()
|
||||
set(INSTALL_TARGET_DIR "${CMAKE_INSTALL_LIBDIR}" CACHE PATH "Path where the libraries will be installed")
|
||||
set(INSTALL_DISPATCH_HEADERS_DIR "include/dispatch" CACHE PATH "Path where the headers will be installed")
|
||||
set(INSTALL_BLOCK_HEADERS_DIR "include" CACHE PATH "Path where the headers will be installed for the blocks runtime")
|
||||
set(INSTALL_OS_HEADERS_DIR "include/os" CACHE PATH "Path where the headers will be installed")
|
||||
endif()
|
||||
|
||||
|
||||
add_subdirectory(dispatch)
|
||||
add_subdirectory(man)
|
||||
add_subdirectory(os)
|
||||
add_subdirectory(private)
|
||||
add_subdirectory(src)
|
||||
if(BUILD_TESTING)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
add_subdirectory(cmake/modules)
|
||||
10
Telegram/ThirdParty/dispatch/CONTRIBUTING.md
vendored
Normal file
10
Telegram/ThirdParty/dispatch/CONTRIBUTING.md
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
By submitting a pull request, you represent that you have the right to license
|
||||
your contribution to Apple and the community, and agree by submitting the patch
|
||||
that your contributions are licensed under the [Swift
|
||||
license](https://swift.org/LICENSE.txt).
|
||||
|
||||
---
|
||||
|
||||
Before submitting the pull request, please make sure you have tested your
|
||||
changes and that they follow the Swift project [guidelines for contributing
|
||||
code](https://swift.org/contributing/#contributing-code).
|
||||
170
Telegram/ThirdParty/dispatch/INSTALL.md
vendored
Normal file
170
Telegram/ThirdParty/dispatch/INSTALL.md
vendored
Normal file
@@ -0,0 +1,170 @@
|
||||
## Grand Central Dispatch (GCD)
|
||||
|
||||
GCD is a concurrent programming framework first shipped with Mac OS X Snow
|
||||
Leopard. This package is an open source bundling of libdispatch, the core
|
||||
user space library implementing GCD. At the time of writing, support for
|
||||
the BSD kqueue API, and specifically extensions introduced in Mac OS X Snow
|
||||
Leopard and FreeBSD 9-CURRENT, are required to use libdispatch. Linux is
|
||||
supported, but requires specific packages to be installed (see Linux
|
||||
section at the end of the file). Other systems are currently unsupported.
|
||||
|
||||
### Configuring and installing libdispatch (general comments)
|
||||
|
||||
GCD is built using autoconf, automake, and libtool, and has a number of
|
||||
compile-time configuration options that should be reviewed before starting.
|
||||
An uncustomized install of the C-API to libdispatch requires:
|
||||
|
||||
sh autogen.sh
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
|
||||
libdispatch can be optionally built to include a Swift API. This requires a
|
||||
Swift toolchain to compile the Swift code in libdispatch and can be done
|
||||
in two possible scenarios.
|
||||
|
||||
If you are building your own Swift toolchain from source, then you should build
|
||||
libdispatch simply by giving additional arguments to swift/utils/build-script:
|
||||
|
||||
./swift/utils/build-script --libdispatch -- --install-libdispatch
|
||||
|
||||
To build libdispatch using a pre-built Swift toolchain and install libdispatch
|
||||
into that toolchain (to allow that toolchain to compile Swift code containing
|
||||
"import Dispatch") requires:
|
||||
|
||||
sh autogen.sh
|
||||
./configure --with-swift-toolchain=<PATH_TO_SWIFT_TOOLCHAIN> --prefix=<PATH_TO_SWIFT_TOOLCHAIN>
|
||||
make
|
||||
make install
|
||||
|
||||
Note that once libdispatch is installed into a Swift toolchain, that
|
||||
toolchain cannot be used to compile libdispatch again (you must 'make uninstall'
|
||||
libdispatch from the toolchain before using it to rebuild libdispatch).
|
||||
|
||||
You can also use the build-toolchain script to create a toolchain
|
||||
that includes libdispatch on Linux:
|
||||
|
||||
1. Add libdispatch and install-libdispatch lines to ./swift/utils/build-presets.ini under `[preset: buildbot_linux]` section, as following:
|
||||
|
||||
```
|
||||
[preset: buildbot_linux]
|
||||
mixin-preset=mixin_linux_installation
|
||||
build-subdir=buildbot_linux
|
||||
lldb
|
||||
release
|
||||
test
|
||||
validation-test
|
||||
long-test
|
||||
libdispatch
|
||||
foundation
|
||||
lit-args=-v
|
||||
dash-dash
|
||||
|
||||
install-libdispatch
|
||||
install-foundation
|
||||
reconfigure
|
||||
```
|
||||
|
||||
2. Run:
|
||||
|
||||
```
|
||||
./swift/utils/build-toolchain local.swift
|
||||
```
|
||||
|
||||
Note that adding libdispatch in build-presets.ini is for Linux only as Swift on macOS platforms uses the system installed libdispatch, so its not required.
|
||||
|
||||
### Building and installing on OS X
|
||||
|
||||
The following configure options may be of general interest:
|
||||
|
||||
`--with-apple-libpthread-source`
|
||||
|
||||
Specify the path to Apple's libpthread package, so that appropriate headers
|
||||
can be found and used.
|
||||
|
||||
`--with-apple-libplatform-source`
|
||||
|
||||
Specify the path to Apple's libplatform package, so that appropriate headers
|
||||
can be found and used.
|
||||
|
||||
`--with-apple-xnu-source`
|
||||
|
||||
Specify the path to Apple's XNU package, so that appropriate headers can be
|
||||
found and used.
|
||||
|
||||
`--with-blocks-runtime`
|
||||
|
||||
On systems where -fblocks is supported, specify an additional library path in which libBlocksRuntime can be found. This is not required on OS X, where the Blocks runtime is included in libSystem, but is required on FreeBSD.
|
||||
|
||||
The following options are likely to only be useful when building libdispatch on
|
||||
OS X as a replacement for /usr/lib/system/libdispatch.dylib:
|
||||
|
||||
`--disable-libdispatch-init-constructor`
|
||||
|
||||
Do not tag libdispatch's init routine as __constructor, in which case it must be run manually before libdispatch routines can be called. This is the default when building on OS X. For /usr/lib/system/libdispatch.dylib the init routine is called automatically during process start.
|
||||
|
||||
`--enable-apple-tsd-optimizations`
|
||||
|
||||
Use a non-portable allocation scheme for pthread per-thread data (TSD) keys when building libdispatch for /usr/lib/system on OS X. This should not be used on other OS's, or on OS X when building a stand-alone library.
|
||||
|
||||
#### Typical configuration commands
|
||||
|
||||
The following command lines create the configuration required to build
|
||||
libdispatch for /usr/lib/system on OS X El Capitan:
|
||||
|
||||
clangpath=$(dirname `xcrun --find clang`)
|
||||
sudo mkdir -p "$clangpath/../local/lib/clang/enable_objc_gc"
|
||||
LIBTOOLIZE=glibtoolize sh autogen.sh
|
||||
cflags='-arch x86_64 -arch i386 -g -Os'
|
||||
./configure CFLAGS="$cflags" OBJCFLAGS="$cflags" CXXFLAGS="$cflags" \
|
||||
--prefix=/usr --libdir=/usr/lib/system --disable-static \
|
||||
--enable-apple-tsd-optimizations \
|
||||
--with-apple-libpthread-source=/path/to/10.11.0/libpthread-137.1.1 \
|
||||
--with-apple-libplatform-source=/path/to/10.11.0/libplatform-73.1.1 \
|
||||
--with-apple-xnu-source=/path/to/10.11.0/xnu-3247.1.106 \
|
||||
make check
|
||||
|
||||
### Building and installing for FreeBSD
|
||||
|
||||
Typical configuration line for FreeBSD 8.x and 9.x to build libdispatch with
|
||||
clang and blocks support:
|
||||
|
||||
```
|
||||
cmake -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DBlocksRuntime_INCLUDE_DIR=/usr/local/include -DBlocksRuntime_LIBRARIES=/usr/local/lib/libBlocksRuntime.so <path-to-source>
|
||||
ninja
|
||||
ninja test
|
||||
```
|
||||
|
||||
### Building for android
|
||||
|
||||
Note that this assumes that you are building on Linux. It requires that you
|
||||
have the android NDK available. It has been tested against API Level 21.
|
||||
|
||||
```
|
||||
cmake -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_SYSTEM_NAME=Android -DCMAKE_SYSTEM_VERSION=21 -DCMAKE_ANDROID_NDK=<path to android NDK> <path-to-source>
|
||||
ninja
|
||||
```
|
||||
|
||||
### Building and installing for Linux
|
||||
|
||||
Note that libdispatch development and testing is done only
|
||||
on Ubuntu; currently supported versions are 14.04, 15.10 and 16.04.
|
||||
|
||||
1. The first thing to do is install required packages:
|
||||
|
||||
`sudo apt-get install cmake ninja-build clang systemtap-sdt-dev libbsd-dev linux-libc-dev`
|
||||
|
||||
Note: compiling libdispatch requires clang 3.8 or better and
|
||||
the gold linker. If the default clang on your Ubuntu version is
|
||||
too old, see http://apt.llvm.org/ to install a newer version.
|
||||
On older Ubuntu releases, you may need to install binutils-gold
|
||||
to get the gold linker.
|
||||
|
||||
2. Build
|
||||
|
||||
```
|
||||
cmake -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ <path-to-source>
|
||||
ninja
|
||||
ninja install
|
||||
```
|
||||
|
||||
211
Telegram/ThirdParty/dispatch/LICENSE
vendored
Normal file
211
Telegram/ThirdParty/dispatch/LICENSE
vendored
Normal file
@@ -0,0 +1,211 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
|
||||
|
||||
### Runtime Library Exception to the Apache 2.0 License: ###
|
||||
|
||||
|
||||
As an exception, if you use this Software to compile your source code and
|
||||
portions of this Software are embedded into the binary product as a result,
|
||||
you may redistribute such product without providing attribution as would
|
||||
otherwise be required by Sections 4(a), 4(b) and 4(d) of the License.
|
||||
436
Telegram/ThirdParty/dispatch/PATCHES
vendored
Normal file
436
Telegram/ThirdParty/dispatch/PATCHES
vendored
Normal file
@@ -0,0 +1,436 @@
|
||||
The libdispatch project exists in a parallel open source repository at:
|
||||
http://github.com/apple/swift-corelibs-libdispatch
|
||||
|
||||
Externally contributed changes are synchronized back to the internal repository
|
||||
via pull request of the result of `git am` of the contributed patch series.
|
||||
|
||||
Internal changes are synchronized from the internal darwin/trunk branch to the
|
||||
external repository via `gi am` on the github darwin/trunk branch and merge to
|
||||
github master.
|
||||
|
||||
Key:
|
||||
APPLIED: change set was applied to internal repository.
|
||||
INTERNAL: change set originated internally (i.e. already applied).
|
||||
SKIPPED: change set was skipped.
|
||||
|
||||
svn revisions until r218 from legacy open source repository at
|
||||
http://svn.macosforge.org/repository/libdispatch/trunk
|
||||
|
||||
[ 1] SKIPPED
|
||||
[ 2] SKIPPED
|
||||
[ 3] INTERNAL rdar://problem/7148356
|
||||
[ 4] APPLIED rdar://problem/7323245
|
||||
[ 5] APPLIED rdar://problem/7323245
|
||||
[ 6] APPLIED rdar://problem/7323245
|
||||
[ 7] APPLIED rdar://problem/7323245
|
||||
[ 8] APPLIED rdar://problem/7323245
|
||||
[ 9] APPLIED rdar://problem/7323245
|
||||
[ 10] APPLIED rdar://problem/7323245
|
||||
[ 11] APPLIED rdar://problem/7323245
|
||||
[ 12] APPLIED rdar://problem/7323245
|
||||
[ 13] SKIPPED
|
||||
[ 14] APPLIED rdar://problem/7323245
|
||||
[ 15] APPLIED rdar://problem/7323245
|
||||
[ 16] APPLIED rdar://problem/7323245
|
||||
[ 17] APPLIED rdar://problem/7323245
|
||||
[ 18] APPLIED rdar://problem/7323245
|
||||
[ 19] APPLIED rdar://problem/7323245
|
||||
[ 20] APPLIED rdar://problem/7323245
|
||||
[ 21] APPLIED rdar://problem/7323245
|
||||
[ 22] APPLIED rdar://problem/7323245
|
||||
[ 23] APPLIED rdar://problem/7323245
|
||||
[ 24] APPLIED rdar://problem/7323245
|
||||
[ 25] APPLIED rdar://problem/7323245
|
||||
[ 26] APPLIED rdar://problem/7323245
|
||||
[ 27] APPLIED rdar://problem/7323245
|
||||
[ 28] APPLIED rdar://problem/7323245
|
||||
[ 29] APPLIED rdar://problem/7323245
|
||||
[ 30] SKIPPED
|
||||
[ 31] APPLIED rdar://problem/7323245
|
||||
[ 32] APPLIED rdar://problem/7323245
|
||||
[ 33] APPLIED rdar://problem/7323245
|
||||
[ 34] APPLIED rdar://problem/7323245
|
||||
[ 35] SKIPPED
|
||||
[ 36] APPLIED rdar://problem/7323245
|
||||
[ 37] APPLIED rdar://problem/7323245
|
||||
[ 38] APPLIED rdar://problem/7323245
|
||||
[ 39] APPLIED rdar://problem/7323245
|
||||
[ 40] APPLIED rdar://problem/7323245
|
||||
[ 41] APPLIED rdar://problem/7323245
|
||||
[ 42] APPLIED rdar://problem/7323245
|
||||
[ 43] APPLIED rdar://problem/7323245
|
||||
[ 44] APPLIED rdar://problem/7323245
|
||||
[ 45] APPLIED rdar://problem/7323245
|
||||
[ 46] APPLIED rdar://problem/7323245
|
||||
[ 47] APPLIED rdar://problem/7323245
|
||||
[ 48] APPLIED rdar://problem/7323245
|
||||
[ 49] APPLIED rdar://problem/7323245
|
||||
[ 50] APPLIED rdar://problem/7323245
|
||||
[ 51] APPLIED rdar://problem/7323245
|
||||
[ 52] APPLIED rdar://problem/7323245
|
||||
[ 53] APPLIED rdar://problem/7323245
|
||||
[ 54] APPLIED rdar://problem/7323245
|
||||
[ 55] APPLIED rdar://problem/7323245
|
||||
[ 56] APPLIED rdar://problem/7323245
|
||||
[ 57] APPLIED rdar://problem/7323245
|
||||
[ 58] APPLIED rdar://problem/7323245
|
||||
[ 59] APPLIED rdar://problem/7323245
|
||||
[ 60] APPLIED rdar://problem/7323245
|
||||
[ 61] APPLIED rdar://problem/7323245
|
||||
[ 62] APPLIED rdar://problem/7323245
|
||||
[ 63] APPLIED rdar://problem/7323245
|
||||
[ 64] APPLIED rdar://problem/7323245
|
||||
[ 65] APPLIED rdar://problem/7323245
|
||||
[ 66] APPLIED rdar://problem/7323245
|
||||
[ 67] APPLIED rdar://problem/7323245
|
||||
[ 68] APPLIED rdar://problem/7323245
|
||||
[ 69] APPLIED rdar://problem/7323245
|
||||
[ 70] APPLIED rdar://problem/7323245
|
||||
[ 71] INTERNAL
|
||||
[ 72] INTERNAL
|
||||
[ 73] APPLIED rdar://problem/7531526
|
||||
[ 74] APPLIED rdar://problem/7531526
|
||||
[ 75]
|
||||
[ 76]
|
||||
[ 77]
|
||||
[ 78]
|
||||
[ 79] APPLIED rdar://problem/7531526
|
||||
[ 80] APPLIED rdar://problem/7531526
|
||||
[ 81] APPLIED rdar://problem/7531526
|
||||
[ 82] APPLIED rdar://problem/7531526
|
||||
[ 83] APPLIED rdar://problem/7531526
|
||||
[ 84] APPLIED rdar://problem/7531526
|
||||
[ 85]
|
||||
[ 86]
|
||||
[ 87] APPLIED rdar://problem/7531526
|
||||
[ 88] APPLIED rdar://problem/7531526
|
||||
[ 89] APPLIED rdar://problem/7531526
|
||||
[ 90]
|
||||
[ 91]
|
||||
[ 92]
|
||||
[ 93]
|
||||
[ 94]
|
||||
[ 95]
|
||||
[ 96] APPLIED rdar://problem/7531526
|
||||
[ 97] APPLIED rdar://problem/7531526
|
||||
[ 98]
|
||||
[ 99]
|
||||
[ 100]
|
||||
[ 101]
|
||||
[ 102]
|
||||
[ 103] APPLIED rdar://problem/7531526
|
||||
[ 104] APPLIED rdar://problem/7531526
|
||||
[ 105]
|
||||
[ 106] APPLIED rdar://problem/7531526
|
||||
[ 107] SKIPPED
|
||||
[ 108] SKIPPED
|
||||
[ 109] SKIPPED
|
||||
[ 110] SKIPPED
|
||||
[ 111] SKIPPED
|
||||
[ 112] APPLIED rdar://problem/7531526
|
||||
[ 113] SKIPPED
|
||||
[ 114] APPLIED rdar://problem/7531526
|
||||
[ 115] APPLIED rdar://problem/7531526
|
||||
[ 116] APPLIED rdar://problem/7531526
|
||||
[ 117] SKIPPED
|
||||
[ 118] APPLIED rdar://problem/7531526
|
||||
[ 119] SKIPPED
|
||||
[ 120] APPLIED rdar://problem/7531526
|
||||
[ 121] SKIPPED
|
||||
[ 122] SKIPPED
|
||||
[ 123] SKIPPED
|
||||
[ 124] SKIPPED
|
||||
[ 125] APPLIED rdar://problem/7531526
|
||||
[ 126] SKIPPED
|
||||
[ 127] APPLIED rdar://problem/7531526
|
||||
[ 128]
|
||||
[ 129]
|
||||
[ 130]
|
||||
[ 131]
|
||||
[ 132]
|
||||
[ 133]
|
||||
[ 134]
|
||||
[ 135]
|
||||
[ 136]
|
||||
[ 137] APPLIED rdar://problem/7647055
|
||||
[ 138] SKIPPED
|
||||
[ 139] APPLIED rdar://problem/7531526
|
||||
[ 140] APPLIED rdar://problem/7531526
|
||||
[ 141] APPLIED rdar://problem/7531526
|
||||
[ 142] APPLIED rdar://problem/7531526
|
||||
[ 143]
|
||||
[ 144] APPLIED rdar://problem/7531526
|
||||
[ 145] APPLIED rdar://problem/7531526
|
||||
[ 146] APPLIED rdar://problem/7531526
|
||||
[ 147]
|
||||
[ 148]
|
||||
[ 149]
|
||||
[ 150]
|
||||
[ 151] APPLIED rdar://problem/7531526
|
||||
[ 152] APPLIED rdar://problem/7531526
|
||||
[ 153]
|
||||
[ 154] APPLIED rdar://problem/7531526
|
||||
[ 155]
|
||||
[ 156]
|
||||
[ 157] APPLIED rdar://problem/7531526
|
||||
[ 158]
|
||||
[ 159]
|
||||
[ 160]
|
||||
[ 161]
|
||||
[ 162] APPLIED rdar://problem/7531526
|
||||
[ 163] APPLIED rdar://problem/7531526
|
||||
[ 164]
|
||||
[ 165]
|
||||
[ 166] APPLIED rdar://problem/7531526
|
||||
[ 167] APPLIED rdar://problem/7531526
|
||||
[ 168]
|
||||
[ 169] APPLIED rdar://problem/7531526
|
||||
[ 170] APPLIED rdar://problem/7531526
|
||||
[ 171] APPLIED rdar://problem/7531526
|
||||
[ 172] APPLIED rdar://problem/7531526
|
||||
[ 173] APPLIED rdar://problem/7531526
|
||||
[ 174] APPLIED rdar://problem/7531526
|
||||
[ 175] APPLIED rdar://problem/7531526
|
||||
[ 176] APPLIED rdar://problem/7531526
|
||||
[ 177] APPLIED rdar://problem/7531526
|
||||
[ 178]
|
||||
[ 179] APPLIED rdar://problem/7531526
|
||||
[ 180] APPLIED rdar://problem/7531526
|
||||
[ 181]
|
||||
[ 182]
|
||||
[ 183] INTERNAL rdar://problem/7581831
|
||||
[ 202] INTERNAL libdispatch-187.5
|
||||
[ 212] INTERNAL libdispatch-228.18
|
||||
[ 213] INTERNAL rdar://problem/11754320
|
||||
[ 216] INTERNAL libdispatch-339.1.9
|
||||
[ 217] INTERNAL libdispatch-442.1.4
|
||||
[ 218] INTERNAL libdispatch-500.1.5
|
||||
|
||||
github commits starting with 29bdc2f from
|
||||
|
||||
http://github.com/apple/swift-corelibs-libdispatch
|
||||
|
||||
[29bdc2f] INTERNAL libdispatch-500.1.5
|
||||
[a60acd6] APPLIED rdar://23661056
|
||||
[39ac720] APPLIED rdar://23705483
|
||||
[acd56f6] APPLIED rdar://23754944
|
||||
[394d9a1] APPLIED rdar://23772602
|
||||
[3691f26] APPLIED rdar://23868354
|
||||
[8904f45] APPLIED rdar://23868354
|
||||
[6dbebd6] APPLIED rdar://23868354
|
||||
[b2ccfeb] APPLIED rdar://23868354
|
||||
[e7ca00f] APPLIED rdar://23868354
|
||||
[35eb408] APPLIED rdar://25159995
|
||||
[32411c2] APPLIED rdar://25159995
|
||||
[31586d5] APPLIED rdar://25159995
|
||||
[50faff5] APPLIED rdar://25159995
|
||||
[3ce4e3d] APPLIED rdar://25159995
|
||||
[b647aee] APPLIED rdar://25159995
|
||||
[ab7e16c] APPLIED rdar://25159995
|
||||
[cef2960] APPLIED rdar://25159995
|
||||
[dfa43cd] APPLIED rdar://25159995
|
||||
[8b9c3a9] APPLIED rdar://25159995
|
||||
[fefb6cf] APPLIED rdar://25159995
|
||||
[1a9c57f] APPLIED rdar://25159995
|
||||
[c04488a] APPLIED rdar://25159995
|
||||
[f1d58d1] APPLIED rdar://25159995
|
||||
[be83e85] APPLIED rdar://25159995
|
||||
[79fbb13] APPLIED rdar://25159995
|
||||
[6ead519] APPLIED rdar://25159995
|
||||
[1fa1513] APPLIED rdar://25159995
|
||||
[4a6ec51] APPLIED rdar://25159995
|
||||
[bc16cc9] APPLIED rdar://25159995
|
||||
[954ace4] APPLIED rdar://25159995
|
||||
[5ea30b5] APPLIED rdar://26822213
|
||||
[9f1e778] APPLIED rdar://26822213
|
||||
[3339b81] APPLIED rdar://26822213
|
||||
[4fa8d8d] APPLIED rdar://26822213
|
||||
[e922531] APPLIED rdar://26822213
|
||||
[195cbcf] APPLIED rdar://27303844
|
||||
[5b893c8] APPLIED rdar://27303844
|
||||
[92689ed] APPLIED rdar://27303844
|
||||
[ecc14fa] APPLIED rdar://27303844
|
||||
[2dbf83c] APPLIED rdar://27303844
|
||||
[78b9e82] APPLIED rdar://27303844
|
||||
[2c0e5ee] APPLIED rdar://27303844
|
||||
[5ee237f] APPLIED rdar://27600964
|
||||
[77299ec] APPLIED rdar://27600964
|
||||
[57c5c28] APPLIED rdar://27600964
|
||||
[f8423ec] APPLIED rdar://27600964
|
||||
[325f73d] APPLIED rdar://27600964
|
||||
[b84e87e] APPLIED rdar://27600964
|
||||
[ae71a91] APPLIED rdar://27600964
|
||||
[8669dea] APPLIED rdar://27600964
|
||||
[a8d0327] APPLIED rdar://27600964
|
||||
[2e4e6af] APPLIED rdar://27600964
|
||||
[2457fb2] APPLIED rdar://27600964
|
||||
[4d58038] APPLIED rdar://27600964
|
||||
[98d0a05] APPLIED rdar://27600964
|
||||
[8976101] APPLIED rdar://27600964
|
||||
[0d9ea5f] APPLIED rdar://28486911
|
||||
[e7e9a32] APPLIED rdar://28486911
|
||||
[44174d9] APPLIED rdar://28486911
|
||||
[6402cb7] APPLIED rdar://28486911
|
||||
[e2d5eb5] APPLIED rdar://28486911
|
||||
[758bb7f] APPLIED rdar://28486911
|
||||
[4c588e9] APPLIED rdar://28486911
|
||||
[1300d06] APPLIED rdar://28486911
|
||||
[ae1f7e8] APPLIED rdar://28486911
|
||||
[40a9bfb] APPLIED rdar://28486911
|
||||
[6366081] APPLIED rdar://28486911
|
||||
[81d1d0c] APPLIED rdar://28486911
|
||||
[5526122] APPLIED rdar://28486911
|
||||
[1a7ff3f] APPLIED rdar://28486911
|
||||
[e905735] APPLIED rdar://28486911
|
||||
[7fe8323] APPLIED rdar://28486911
|
||||
[6249878] APPLIED rdar://28486911
|
||||
[20792fe] APPLIED rdar://28486911
|
||||
[3639fbe] APPLIED rdar://28486911
|
||||
[bda3baf] APPLIED rdar://28486911
|
||||
[8803d07] APPLIED rdar://28486911
|
||||
[d04a0df] APPLIED rdar://28486911
|
||||
[69d2a6a] APPLIED rdar://28486911
|
||||
[367bd95] APPLIED rdar://28486911
|
||||
[152985f] APPLIED rdar://28486911
|
||||
[ba7802e] APPLIED rdar://28486911
|
||||
[92773e0] APPLIED rdar://30568673
|
||||
[548a1b9] APPLIED rdar://30568673
|
||||
[b628e5c] APPLIED rdar://30568673
|
||||
[a055ddb] APPLIED rdar://30568673
|
||||
[012f48b] APPLIED rdar://30568673
|
||||
[353adba] APPLIED rdar://30568673
|
||||
[eb730eb] APPLIED rdar://30568673
|
||||
[ac16fbb] APPLIED rdar://30568673
|
||||
[967876e] APPLIED rdar://30568673
|
||||
[44c2291] APPLIED rdar://30568673
|
||||
[ceb1fac] APPLIED rdar://30568673
|
||||
[c95febb] APPLIED rdar://30568673
|
||||
[b6e9cf4] APPLIED rdar://30568673
|
||||
[e199473] APPLIED rdar://30568673
|
||||
[3767ac7] APPLIED rdar://30568673
|
||||
[10eb0e4] APPLIED rdar://30568673
|
||||
[787dd92] APPLIED rdar://30568673
|
||||
[ba4cac5] APPLIED rdar://30568673
|
||||
[7974138] APPLIED rdar://30568673
|
||||
[cd12dcb] APPLIED rdar://32283666
|
||||
[ff05109] APPLIED rdar://32283666
|
||||
[73315ee] APPLIED rdar://32283666
|
||||
[fcc1924] APPLIED rdar://32283666
|
||||
[272e818] APPLIED rdar://32283666
|
||||
[b6f8908] APPLIED rdar://32283666
|
||||
[a6c16d0] APPLIED rdar://32283666
|
||||
[1cc64e1] APPLIED rdar://32283666
|
||||
[d137aa4] APPLIED rdar://32283666
|
||||
[a69853f] APPLIED rdar://32283666
|
||||
[eea0667] APPLIED rdar://32283666
|
||||
[f84d21d] APPLIED rdar://32283666
|
||||
[3da8398] APPLIED rdar://32283666
|
||||
[2df80a3] APPLIED rdar://32283666
|
||||
[97a2f06] APPLIED rdar://32283666
|
||||
[f76b8f5] APPLIED rdar://32283666
|
||||
[3828fbb] APPLIED rdar://32283666
|
||||
[5e8789e] APPLIED rdar://32283666
|
||||
[3fba60a] APPLIED rdar://32283666
|
||||
[d6eb245] APPLIED rdar://32283666
|
||||
[0b6c22e] APPLIED rdar://33531111
|
||||
[5a3c02a] APPLIED rdar://33531111
|
||||
[22df1e7] APPLIED rdar://33531111
|
||||
[21273de] APPLIED rdar://33531111
|
||||
[dc1857c] APPLIED rdar://33531111
|
||||
[56f36b6] APPLIED rdar://33531111
|
||||
[c87c6bb] APPLIED rdar://33531111
|
||||
[b791d23] APPLIED rdar://33531111
|
||||
[c2d0c49] APPLIED rdar://33531111
|
||||
[1d25040] APPLIED rdar://33531111
|
||||
[ab89c6c] APPLIED rdar://33531111
|
||||
[e591e7e] APPLIED rdar://33531111
|
||||
[ded5bab] APPLIED rdar://33531111
|
||||
[ce90d0c] APPLIED rdar://33531111
|
||||
[69c8f3e] APPLIED rdar://33531111
|
||||
[23a3a84] APPLIED rdar://33531111
|
||||
[79b7529] APPLIED rdar://33531111
|
||||
[f8e71eb] APPLIED rdar://33531111
|
||||
[8947dcf] APPLIED rdar://33531111
|
||||
[5ad9208] APPLIED rdar://33531111
|
||||
[698d085] APPLIED rdar://33531111
|
||||
[ce1ce45] APPLIED rdar://35017478
|
||||
[291f34d] APPLIED rdar://35017478
|
||||
[666df60] APPLIED rdar://35017478
|
||||
[80dd736] APPLIED rdar://35017478
|
||||
[0fd5a69] APPLIED rdar://35017478
|
||||
[0e35ed9] APPLIED rdar://35017478
|
||||
[70ce56b] APPLIED rdar://35017478
|
||||
[40fc1f3] APPLIED rdar://35017478
|
||||
[9ec74ed] APPLIED rdar://35017478
|
||||
[7f330ed] APPLIED rdar://35017478
|
||||
[947b51c] APPLIED rdar://35017478
|
||||
[295f676] APPLIED rdar://35017478
|
||||
[48196a2] APPLIED rdar://35017478
|
||||
[a28fc2b] APPLIED rdar://35017478
|
||||
[791ce5d] APPLIED rdar://35017478
|
||||
[0d0a998] APPLIED rdar://35017478
|
||||
[29329b5] APPLIED rdar://35017478
|
||||
[141403a] APPLIED rdar://35017478
|
||||
[b7f1beb] APPLIED rdar://35017478
|
||||
[7ef9cde] APPLIED rdar://35017478
|
||||
[12c9ca8] APPLIED rdar://35017478
|
||||
[6d6dc2e] APPLIED rdar://40252515
|
||||
[4a9833d] APPLIED rdar://40252515
|
||||
[f88e382] APPLIED rdar://40252515
|
||||
[bfa9aa7] APPLIED rdar://40252515
|
||||
[44f3640] APPLIED rdar://40252515
|
||||
[3b06f54] APPLIED rdar://40252515
|
||||
[e245cbe] APPLIED rdar://40252515
|
||||
[2a539d6] APPLIED rdar://40252515
|
||||
[e52c174] APPLIED rdar://40252515
|
||||
[723bd98] APPLIED rdar://40252515
|
||||
[7e7a579] APPLIED rdar://40252515
|
||||
[244a5fe] APPLIED rdar://40252515
|
||||
[8b72f76] APPLIED rdar://40252515
|
||||
[f3531a2] APPLIED rdar://40252515
|
||||
[5cf8acb] APPLIED rdar://40252515
|
||||
[dc01e36] APPLIED rdar://40252515
|
||||
[2d6d1fd] APPLIED rdar://40252515
|
||||
[fdd671d] APPLIED rdar://40252515
|
||||
[698220e] APPLIED rdar://40252515
|
||||
[9c792ac] APPLIED rdar://40252515
|
||||
[b5ec5d8] APPLIED rdar://40252515
|
||||
[9295346] APPLIED rdar://40252515
|
||||
[bbf03ca] APPLIED rdar://40252515
|
||||
[8d3aa22] APPLIED rdar://40252515
|
||||
[f151b33] APPLIED rdar://40252515
|
||||
[f6e6917] APPLIED rdar://40252515
|
||||
[f83b5a4] APPLIED rdar://40252515
|
||||
[c4d6402] APPLIED rdar://40252515
|
||||
[1457de8] APPLIED rdar://40252515
|
||||
[c025baa] APPLIED rdar://40252515
|
||||
[a618b46] APPLIED rdar://40252515
|
||||
[e723a8e] APPLIED rdar://44568645
|
||||
[4ac77b7] APPLIED rdar://44568645
|
||||
[03696d7] APPLIED rdar://44568645
|
||||
[44f67b2] APPLIED rdar://44568645
|
||||
[b15ee59] APPLIED rdar://44568645
|
||||
[d29ed37] APPLIED rdar://44568645
|
||||
[65ebc0c] APPLIED rdar://44568645
|
||||
[93c64d8] APPLIED rdar://44568645
|
||||
[1271df6] APPLIED rdar://44568645
|
||||
[84ac6ac] APPLIED rdar://44568645
|
||||
[30d3c8c] APPLIED rdar://44568645
|
||||
[12ff819] APPLIED rdar://44568645
|
||||
[82342ee] APPLIED rdar://44568645
|
||||
[b13a51e] APPLIED rdar://44568645
|
||||
[6bf3065] APPLIED rdar://44568645
|
||||
[631821c] APPLIED rdar://44568645
|
||||
[e764f34] APPLIED rdar://44568645
|
||||
[ff1daf8] APPLIED rdar://44568645
|
||||
[b863538] APPLIED rdar://44568645
|
||||
[ba3933d] APPLIED rdar://44568645
|
||||
[9c48a80] APPLIED rdar://44568645
|
||||
[5f49e8b] APPLIED rdar://44568645
|
||||
[653a523] APPLIED rdar://44568645
|
||||
[ac5f4c4] APPLIED rdar://44568645
|
||||
[57139c6] APPLIED rdar://44568645
|
||||
[ba74b6a] APPLIED rdar://44568645
|
||||
[3975b58] APPLIED rdar://44568645
|
||||
[81dc900] APPLIED rdar://44568645
|
||||
[6162a1d] APPLIED rdar://44568645
|
||||
24
Telegram/ThirdParty/dispatch/README.md
vendored
Normal file
24
Telegram/ThirdParty/dispatch/README.md
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
# Grand Central Dispatch
|
||||
|
||||
Grand Central Dispatch (GCD or libdispatch) provides comprehensive support for concurrent code execution on multicore hardware.
|
||||
|
||||
libdispatch is currently available on all Darwin platforms. This project aims to make a modern version of libdispatch available on all other Swift platforms. To do this, we will implement as much of the portable subset of the API as possible, using the existing open source C implementation.
|
||||
|
||||
libdispatch on Darwin is a combination of logic in the `xnu` kernel alongside the user-space Library. The kernel has the most information available to balance workload across the entire system. As a first step, however, we believe it is useful to bring up the basic functionality of the library using user-space pthread primitives on Linux. Eventually, a Linux kernel module could be developed to support more informed thread scheduling.
|
||||
|
||||
## Project Status
|
||||
|
||||
A port of libdispatch to Linux has been completed. On Linux, since Swift 3, swift-corelibs-libdispatch has been included in all Swift releases and is used by other swift-corelibs projects.
|
||||
|
||||
Opportunities to contribute and on-going work include:
|
||||
|
||||
1. Develop a test suite for the Swift APIs of libdispatch.
|
||||
2. Enhance libdispatch as needed to support Swift language evolution and the needs of the other Core Libraries projects.
|
||||
|
||||
## Build and Install
|
||||
|
||||
For detailed instructions on building and installing libdispatch, see [INSTALL.md](INSTALL.md)
|
||||
|
||||
## Testing
|
||||
|
||||
For detailed instructions on testing libdispatch, see [TESTING.md](TESTING.md)
|
||||
27
Telegram/ThirdParty/dispatch/TESTING.md
vendored
Normal file
27
Telegram/ThirdParty/dispatch/TESTING.md
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
## Testing libdispatch
|
||||
|
||||
### Running tests
|
||||
|
||||
A C-based test suite can be found in the tests subdirectory.
|
||||
It uses the automake testing harness to execute the tests.
|
||||
|
||||
A default set of tests that are always expected to pass can
|
||||
be executed by doing
|
||||
|
||||
```
|
||||
make check
|
||||
```
|
||||
|
||||
An extended test suite that includes some tests that may fail
|
||||
occasionally can be enabled at configure time:
|
||||
|
||||
```
|
||||
./configure --enable-extended-test-suite
|
||||
make check
|
||||
```
|
||||
|
||||
### Additional prerequisites
|
||||
|
||||
A few test cases require additional packages to be installed.
|
||||
In particular, several IO tests assume /usr/bin/vi is available
|
||||
as an input file and will fail if it is not present.
|
||||
259
Telegram/ThirdParty/dispatch/cmake/config.h.in
vendored
Normal file
259
Telegram/ThirdParty/dispatch/cmake/config.h.in
vendored
Normal file
@@ -0,0 +1,259 @@
|
||||
|
||||
/* Define if building pthread work queues from source */
|
||||
#cmakedefine01 DISPATCH_USE_INTERNAL_WORKQUEUE
|
||||
|
||||
/* Enable usage of thread local storage via _Thread_local */
|
||||
#cmakedefine01 DISPATCH_USE_THREAD_LOCAL_STORAGE
|
||||
|
||||
/* Define to 1 if you have the declaration of `CLOCK_MONOTONIC', and to 0 if
|
||||
you don't. */
|
||||
#cmakedefine01 HAVE_DECL_CLOCK_MONOTONIC
|
||||
|
||||
/* Define to 1 if you have the declaration of `CLOCK_REALTIME', and to 0 if
|
||||
you don't. */
|
||||
#cmakedefine01 HAVE_DECL_CLOCK_REALTIME
|
||||
|
||||
/* Define to 1 if you have the declaration of `CLOCK_UPTIME', and to 0 if you
|
||||
don't. */
|
||||
#cmakedefine01 HAVE_DECL_CLOCK_UPTIME
|
||||
|
||||
/* Define to 1 if you have the declaration of `CLOCK_UPTIME_FAST', and to 0 if
|
||||
you don't. */
|
||||
#cmakedefine01 HAVE_DECL_CLOCK_UPTIME_FAST
|
||||
|
||||
/* Define to 1 if you have the declaration of `CLOCK_MONOTONIC_COARSE', and to
|
||||
0 if you don't. */
|
||||
#cmakedefine01 HAVE_CLOCK_MONOTONIC_COARSE
|
||||
|
||||
/* Define to 1 if you have the declaration of `FD_COPY', and to 0 if you
|
||||
don't. */
|
||||
#cmakedefine01 HAVE_DECL_FD_COPY
|
||||
|
||||
/* Define to 1 if you have the declaration of `NOTE_LOWAT', and to 0 if you
|
||||
don't. */
|
||||
#cmakedefine01 HAVE_DECL_NOTE_LOWAT
|
||||
|
||||
/* Define to 1 if you have the declaration of `NOTE_NONE', and to 0 if you
|
||||
don't. */
|
||||
#cmakedefine01 HAVE_DECL_NOTE_NONE
|
||||
|
||||
/* Define to 1 if you have the declaration of `NOTE_REAP', and to 0 if you
|
||||
don't. */
|
||||
#cmakedefine01 HAVE_DECL_NOTE_REAP
|
||||
|
||||
/* Define to 1 if you have the declaration of `NOTE_REVOKE', and to 0 if you
|
||||
don't. */
|
||||
#cmakedefine01 HAVE_DECL_NOTE_REVOKE
|
||||
|
||||
/* Define to 1 if you have the declaration of `NOTE_SIGNAL', and to 0 if you
|
||||
don't. */
|
||||
#cmakedefine01 HAVE_DECL_NOTE_SIGNAL
|
||||
|
||||
/* Define to 1 if you have the declaration of `POSIX_SPAWN_START_SUSPENDED',
|
||||
and to 0 if you don't. */
|
||||
#cmakedefine01 HAVE_DECL_POSIX_SPAWN_START_SUSPENDED
|
||||
|
||||
/* Define to 1 if you have the declaration of `program_invocation_short_name',
|
||||
and to 0 if you don't. */
|
||||
#cmakedefine01 HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME
|
||||
|
||||
/* Define to 1 if you have the declaration of `SIGEMT', and to 0 if you don't.
|
||||
*/
|
||||
#cmakedefine01 HAVE_DECL_SIGEMT
|
||||
|
||||
/* Define to 1 if you have the declaration of `VQ_DESIRED_DISK', and to 0 if
|
||||
you don't. */
|
||||
#cmakedefine01 HAVE_DECL_VQ_DESIRED_DISK
|
||||
|
||||
/* Define to 1 if you have the declaration of `VQ_NEARLOWDISK', and to 0 if
|
||||
you don't. */
|
||||
#cmakedefine01 HAVE_DECL_VQ_NEARLOWDISK
|
||||
|
||||
/* Define to 1 if you have the declaration of `VQ_QUOTA', and to 0 if you
|
||||
don't. */
|
||||
#cmakedefine01 HAVE_DECL_VQ_QUOTA
|
||||
|
||||
/* Define to 1 if you have the declaration of `VQ_UPDATE', and to 0 if you
|
||||
don't. */
|
||||
#cmakedefine01 HAVE_DECL_VQ_UPDATE
|
||||
|
||||
/* Define to 1 if you have the declaration of `VQ_VERYLOWDISK', and to 0 if
|
||||
you don't. */
|
||||
#cmakedefine01 HAVE_DECL_VQ_VERYLOWDISK
|
||||
|
||||
/* Define to 1 if you have the declaration of `VQ_FREE_SPACE_CHANGE', and to 0 if
|
||||
you don't. */
|
||||
#cmakedefine01 HAVE_DECL_VQ_FREE_SPACE_CHANGE
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#cmakedefine01 HAVE_DLFCN_H
|
||||
|
||||
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||
#cmakedefine01 HAVE_FCNTL_H
|
||||
|
||||
/* Define to 1 if you have the `getprogname' function. */
|
||||
#cmakedefine01 HAVE_GETPROGNAME
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#cmakedefine01 HAVE_INTTYPES_H
|
||||
|
||||
/* Define if Apple leaks program is present */
|
||||
#cmakedefine HAVE_LEAKS
|
||||
|
||||
/* Define to 1 if you have the <libkern/OSAtomic.h> header file. */
|
||||
#cmakedefine HAVE_LIBKERN_OSATOMIC_H
|
||||
|
||||
/* Define to 1 if you have the <libkern/OSCrossEndian.h> header file. */
|
||||
#cmakedefine HAVE_LIBKERN_OSCROSSENDIAN_H
|
||||
|
||||
/* Define to 1 if you have the <libproc_internal.h> header file. */
|
||||
#cmakedefine HAVE_LIBPROC_INTERNAL_H
|
||||
|
||||
/* Define if mach is present */
|
||||
#cmakedefine HAVE_MACH
|
||||
|
||||
/* Define to 1 if you have the `mach_absolute_time' function. */
|
||||
#cmakedefine HAVE_MACH_ABSOLUTE_TIME
|
||||
|
||||
/* Define to 1 if you have the `mach_approximate_time' function. */
|
||||
#cmakedefine HAVE_MACH_APPROXIMATE_TIME
|
||||
|
||||
/* Define to 1 if you have the `mach_port_construct' function. */
|
||||
#cmakedefine HAVE_MACH_PORT_CONSTRUCT
|
||||
|
||||
/* Define to 1 if you have the `malloc_create_zone' function. */
|
||||
#cmakedefine HAVE_MALLOC_CREATE_ZONE
|
||||
|
||||
/* Define to 1 if you have the <malloc/malloc.h> header file. */
|
||||
#cmakedefine HAVE_MALLOC_MALLOC_H
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#cmakedefine01 HAVE_MEMORY_H
|
||||
|
||||
/* Define if __builtin_trap marked noreturn */
|
||||
#cmakedefine01 HAVE_NORETURN_BUILTIN_TRAP
|
||||
|
||||
/* Define if you have the Objective-C runtime */
|
||||
#cmakedefine HAVE_OBJC
|
||||
|
||||
/* Define to 1 if you have the `posix_fadvise' function. */
|
||||
#cmakedefine HAVE_POSIX_FADVISE
|
||||
|
||||
/* Define to 1 if you have the `posix_spawnp' function. */
|
||||
#cmakedefine HAVE_POSIX_SPAWNP
|
||||
|
||||
/* Define to 1 if you have the `pthread_key_init_np' function. */
|
||||
#cmakedefine HAVE_PTHREAD_KEY_INIT_NP
|
||||
|
||||
/* Define to 1 if you have the `pthread_attr_setcpupercent_np' function. */
|
||||
#cmakedefine HAVE_PTHREAD_ATTR_SETCPUPERCENT_NP
|
||||
|
||||
/* Define to 1 if you have the <pthread_machdep.h> header file. */
|
||||
#cmakedefine HAVE_PTHREAD_MACHDEP_H
|
||||
|
||||
/* Define to 1 if you have the `pthread_main_np' function. */
|
||||
#cmakedefine01 HAVE_PTHREAD_MAIN_NP
|
||||
|
||||
/* Define to 1 if you have the `pthread_yield_np' function. */
|
||||
#cmakedefine01 HAVE_PTHREAD_YIELD_NP
|
||||
|
||||
/* Define to 1 if you have the <pthread_np.h> header file. */
|
||||
#cmakedefine01 HAVE_PTHREAD_NP_H
|
||||
|
||||
/* Define to 1 if you have the <pthread/qos.h> header file. */
|
||||
#cmakedefine HAVE_PTHREAD_QOS_H
|
||||
|
||||
/* Define if pthread work queues are present */
|
||||
#cmakedefine01 HAVE_PTHREAD_WORKQUEUES
|
||||
|
||||
/* Define to 1 if you have the <pthread_workqueue.h> header file. */
|
||||
#cmakedefine HAVE_PTHREAD_WORKQUEUE_H
|
||||
|
||||
/* Define to 1 if you have the <pthread/workqueue_private.h> header file. */
|
||||
#cmakedefine HAVE_PTHREAD_WORKQUEUE_PRIVATE_H
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#cmakedefine01 HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#cmakedefine01 HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#cmakedefine01 HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#cmakedefine01 HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the `strlcpy' function. */
|
||||
#cmakedefine01 HAVE_STRLCPY
|
||||
|
||||
/* Define if building for Swift */
|
||||
#undef HAVE_SWIFT
|
||||
|
||||
/* Define to 1 if you have the `sysconf' function. */
|
||||
#cmakedefine01 HAVE_SYSCONF
|
||||
|
||||
/* Define to 1 if you have the <sys/guarded.h> header file. */
|
||||
#cmakedefine HAVE_SYS_GUARDED_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#cmakedefine01 HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#cmakedefine01 HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <TargetConditionals.h> header file. */
|
||||
#cmakedefine HAVE_TARGETCONDITIONALS_H
|
||||
|
||||
/* Define to 1 if you have the `_pthread_workqueue_init' function. */
|
||||
#cmakedefine HAVE__PTHREAD_WORKQUEUE_INIT
|
||||
|
||||
/* Define to use non-portable pthread TSD optimizations for Mac OS X) */
|
||||
#cmakedefine USE_APPLE_TSD_OPTIMIZATIONS
|
||||
|
||||
/* Define to tag libdispatch_init as a constructor */
|
||||
#cmakedefine01 USE_LIBDISPATCH_INIT_CONSTRUCTOR
|
||||
|
||||
/* Define to use Mach semaphores */
|
||||
#cmakedefine USE_MACH_SEM
|
||||
|
||||
/* Define to use POSIX semaphores */
|
||||
#cmakedefine01 USE_POSIX_SEM
|
||||
|
||||
/* Enable extensions on AIX 3, Interix. */
|
||||
#ifndef _ALL_SOURCE
|
||||
#cmakedefine01 _ALL_SOURCE
|
||||
#endif
|
||||
/* Enable GNU extensions on systems that have them. */
|
||||
#ifndef _GNU_SOURCE
|
||||
#cmakedefine _GNU_SOURCE
|
||||
#endif
|
||||
/* Enable threading extensions on Solaris. */
|
||||
#ifndef _POSIX_PTHREAD_SEMANTICS
|
||||
#cmakedefine01 _POSIX_PTHREAD_SEMANTICS
|
||||
#endif
|
||||
/* Enable extensions on HP NonStop. */
|
||||
#ifndef _TANDEM_SOURCE
|
||||
#cmakedefine01 _TANDEM_SOURCE
|
||||
#endif
|
||||
/* Enable general extensions on Solaris. */
|
||||
#ifndef __EXTENSIONS__
|
||||
#cmakedefine01 __EXTENSIONS__
|
||||
#endif
|
||||
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "${PROJECT_VERSION}"
|
||||
|
||||
/* Define to 1 if on MINIX. */
|
||||
#cmakedefine _MINIX
|
||||
|
||||
/* Define to 2 if the system does not provide POSIX.1 features except with
|
||||
this defined. */
|
||||
#cmakedefine _POSIX_1_SOURCE
|
||||
|
||||
/* Define to 1 if you need to in order for `stat' and other things to work. */
|
||||
#cmakedefine _POSIX_SOURCE
|
||||
|
||||
/* Define if using Darwin $NOCANCEL */
|
||||
#cmakedefine __DARWIN_NON_CANCELABLE
|
||||
7
Telegram/ThirdParty/dispatch/cmake/modules/CMakeLists.txt
vendored
Normal file
7
Telegram/ThirdParty/dispatch/cmake/modules/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
set(DISPATCH_EXPORTS_FILE ${CMAKE_CURRENT_BINARY_DIR}/dispatchExports.cmake)
|
||||
configure_file(dispatchConfig.cmake.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/dispatchConfig.cmake)
|
||||
|
||||
get_property(DISPATCH_EXPORTS GLOBAL PROPERTY DISPATCH_EXPORTS)
|
||||
export(TARGETS ${DISPATCH_EXPORTS} FILE ${DISPATCH_EXPORTS_FILE})
|
||||
5
Telegram/ThirdParty/dispatch/cmake/modules/ClangClCompileRules.cmake
vendored
Normal file
5
Telegram/ThirdParty/dispatch/cmake/modules/ClangClCompileRules.cmake
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
|
||||
# clang-cl interprets paths starting with /U as macro undefines, so we need to
|
||||
# put a -- before the input file path to force it to be treated as a path.
|
||||
string(REPLACE "-c <SOURCE>" "-c -- <SOURCE>" CMAKE_C_COMPILE_OBJECT "${CMAKE_C_COMPILE_OBJECT}")
|
||||
string(REPLACE "-c <SOURCE>" "-c -- <SOURCE>" CMAKE_CXX_COMPILE_OBJECT "${CMAKE_CXX_COMPILE_OBJECT}")
|
||||
26
Telegram/ThirdParty/dispatch/cmake/modules/DTrace.cmake
vendored
Normal file
26
Telegram/ThirdParty/dispatch/cmake/modules/DTrace.cmake
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
|
||||
function(dtrace_usdt_probe script)
|
||||
set(options)
|
||||
set(single_parameter_options TARGET_NAME OUTPUT_SOURCES)
|
||||
set(multiple_parameter_options)
|
||||
|
||||
cmake_parse_arguments("" "${options}" "${single_parameter_options}" "${multiple_parameter_options}" ${ARGN})
|
||||
|
||||
get_filename_component(script_we ${script} NAME_WE)
|
||||
|
||||
add_custom_command(OUTPUT
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${script_we}.h
|
||||
COMMAND
|
||||
${dtrace_EXECUTABLE} -h -s ${script} -o ${CMAKE_CURRENT_BINARY_DIR}/${script_we}.h
|
||||
DEPENDS
|
||||
${script})
|
||||
add_custom_target(dtrace-usdt-header-${script_we}
|
||||
DEPENDS
|
||||
${CMAKE_CURRENT_BINARY_DIR}/${script_we}.h)
|
||||
if(_TARGET_NAME)
|
||||
set(${_TARGET_NAME} dtrace-usdt-header-${script_we} PARENT_SCOPE)
|
||||
endif()
|
||||
if(_OUTPUT_SOURCES)
|
||||
set(${_OUTPUT_SOURCES} ${CMAKE_CURRENT_BINARY_DIR}/${script_we}.h PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
43
Telegram/ThirdParty/dispatch/cmake/modules/DispatchAppleOptions.cmake
vendored
Normal file
43
Telegram/ThirdParty/dispatch/cmake/modules/DispatchAppleOptions.cmake
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
|
||||
set(WITH_APPLE_PTHREAD_SOURCE "" CACHE PATH "Path to Apple's libpthread")
|
||||
set(WITH_APPLE_LIBPLATFORM_SOURCE "" CACHE PATH "Path to Apple's libplatform")
|
||||
set(WITH_APPLE_LIBCLOSURE_SOURCE "" CACHE PATH "Path to Apple's libclosure")
|
||||
set(WITH_APPLE_XNU_SOURCE "" CACHE PATH "Path to Apple's XNU")
|
||||
set(WITH_APPLE_OBJC4_SOURCE "" CACHE PATH "Path to Apple's ObjC4")
|
||||
|
||||
if(WITH_APPLE_PTHREAD_SOURCE)
|
||||
include_directories(SYSTEM "${WITH_APPLE_PTHREAD_SOURCE}")
|
||||
endif()
|
||||
if(WITH_APPLE_LIBPLATFORM_SOURCE)
|
||||
include_directories(SYSTEM "${WITH_APPLE_LIBPLATFORM_SOURCE}/include")
|
||||
endif()
|
||||
if(WITH_APPLE_LIBCLOSURE_SOURCE)
|
||||
include_directories(SYSTEM "${WITH_APPLE_LIBCLOSURE_SOURCE}")
|
||||
endif()
|
||||
if(WITH_APPLE_XNU_SOURCE)
|
||||
# FIXME(compnerd) this should use -idirafter
|
||||
include_directories("${WITH_APPLE_XNU_SOURCE}/libkern")
|
||||
include_directories(SYSTEM
|
||||
"${WITH_APPLE_XNU_SOURCE}/bsd"
|
||||
"${WITH_APPLE_XNU_SOURCE}/libsyscall"
|
||||
"${WITH_APPLE_XNU_SOURCE}/libsyscall/wrappers/libproc")
|
||||
|
||||
# hack for xnu/bsd/sys/event.h EVFILT_SOCK declaration
|
||||
add_definitions(-DPRIVATE=1)
|
||||
endif()
|
||||
|
||||
if(IS_DIRECTORY "/System/Library/Frameworks/System.framework/PrivateHeaders")
|
||||
include_directories(SYSTEM
|
||||
"/System/Library/Frameworks/System.framework/PrivateHeaders")
|
||||
endif()
|
||||
|
||||
option(ENABLE_APPLE_TSD_OPTIMIZATIONS "use non-portable pthread TSD optimizations" OFF)
|
||||
if(ENABLE_APPLE_TSD_OPTIMIZATIONS)
|
||||
set(USE_APPLE_TSD_OPTIMIZATIONS 1)
|
||||
else()
|
||||
set(USE_APPLE_TSD_OPTIMIZATIONS 0)
|
||||
endif()
|
||||
|
||||
# TODO(compnerd) link in libpthread headers
|
||||
|
||||
|
||||
84
Telegram/ThirdParty/dispatch/cmake/modules/DispatchCompilerWarnings.cmake
vendored
Normal file
84
Telegram/ThirdParty/dispatch/cmake/modules/DispatchCompilerWarnings.cmake
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
|
||||
if("${CMAKE_C_SIMULATE_ID}" STREQUAL "MSVC")
|
||||
# TODO: someone needs to provide the msvc equivalent warning flags
|
||||
elseif(WIN32)
|
||||
# Tareting Windows but using a non-MSVC compiler. Set -fms-extensions
|
||||
# so that we can use __popcnt64
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-fms-extensions>)
|
||||
else()
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Werror>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wall>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wextra>)
|
||||
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Warray-bounds-pointer-arithmetic>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wassign-enum>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Watomic-properties>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wcomma>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wconditional-uninitialized>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wconversion>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wcovered-switch-default>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wdate-time>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wdeprecated>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wdocumentation>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wdouble-promotion>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wduplicate-enum>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wexpansion-to-defined>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wfloat-equal>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Widiomatic-parentheses>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Winfinite-recursion>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wmissing-prototypes>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wnewline-eof>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wnullable-to-nonnull-conversion>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wobjc-interface-ivars>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wover-aligned>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wpacked>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wpointer-arith>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wselector>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wshadow>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wshorten-64-to-32>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wsign-conversion>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wstatic-in-inline>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wsuper-class-method-mismatch>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wswitch>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wunguarded-availability>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wunreachable-code>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wunused>)
|
||||
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-unknown-warning-option>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-trigraphs>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-four-char-constants>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-disabled-macro-expansion>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-pedantic>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-bad-function-cast>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-c++-compat>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-c++98-compat>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-c++98-compat-pedantic>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-cast-align>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-cast-qual>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-documentation-unknown-command>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-format-nonliteral>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-missing-variable-declarations>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-old-style-cast>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-padded>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-reserved-id-macro>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-shift-sign-overflow>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-undef>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-unreachable-code-aggressive>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-unused-macros>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-used-but-marked-unused>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-void-pointer-to-int-cast>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-vla>)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL Android)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-incompatible-function-pointer-types>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-implicit-function-declaration>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-conversion>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-int-conversion>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-shorten-64-to-32>)
|
||||
endif()
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-error=assign-enum>)
|
||||
|
||||
# Should re-enable after rdar://133498289 is fixed (ie. fixing the one mismatched cast in apply.c)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-cast-function-type-mismatch>)
|
||||
add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-Wno-error=unknown-warning-option>)
|
||||
endif()
|
||||
44
Telegram/ThirdParty/dispatch/cmake/modules/DispatchSanitization.cmake
vendored
Normal file
44
Telegram/ThirdParty/dispatch/cmake/modules/DispatchSanitization.cmake
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
|
||||
set(DISPATCH_USE_SANITIZER "" CACHE STRING
|
||||
"Define the sanitizer used to build binaries and tests.")
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL Darwin AND DISPATCH_USE_SANITIZER)
|
||||
message(FATAL_ERROR "building libdispatch with sanitization is not supported on Darwin")
|
||||
endif()
|
||||
|
||||
if(DISPATCH_USE_SANITIZER)
|
||||
# TODO(compnerd) ensure that the compiler supports these options before adding
|
||||
# them. At the moment, assume that this will just be used with a GNU
|
||||
# compatible driver and that the options are spelt correctly in light of that.
|
||||
add_compile_options("-fno-omit-frame-pointer")
|
||||
if(CMAKE_BUILD_TYPE MATCHES "Debug")
|
||||
add_compile_options("-O1")
|
||||
elseif(NOT CMAKE_BUILD_TYPE MATCHES "Debug" AND
|
||||
NOT CMAKE_BUILD_TYPE MATCHES "RelWithDebInfo")
|
||||
add_compile_options("-gline-tables-only")
|
||||
endif()
|
||||
|
||||
if(LLVM_USE_SANITIZER STREQUAL "Address")
|
||||
add_compile_options("-fsanitize=address")
|
||||
elseif(DISPATCH_USE_SANITIZER MATCHES "Memory(WithOrigins)?")
|
||||
add_compile_options("-fsanitize=memory")
|
||||
if(DISPATCH_USE_SANITIZER STREQUAL "MemoryWithOrigins")
|
||||
add_compile_options("-fsanitize-memory-track-origins")
|
||||
endif()
|
||||
elseif(DISPATCH_USE_SANITIZER STREQUAL "Undefined")
|
||||
add_compile_options("-fsanitize=undefined")
|
||||
add_compile_options("-fno-sanitize=vptr,function")
|
||||
add_compile_options("-fno-sanitize-recover=all")
|
||||
elseif(DISPATCH_USE_SANITIZER STREQUAL "Thread")
|
||||
add_compile_options("-fsanitize=thread")
|
||||
elseif(DISPATCH_USE_SANITIZER STREQUAL "Address;Undefined" OR
|
||||
DISPATCH_USE_SANITIZER STREQUAL "Undefined;Address")
|
||||
add_compile_options("-fsanitize=address,undefined")
|
||||
add_compile_options("-fno-sanitize=vptr,function")
|
||||
add_compile_options("-fno-sanitize-recover=all")
|
||||
elseif(DISPATCH_USE_SANITIZER STREQUAL "Leaks")
|
||||
add_compile_options("-fsanitize=leak")
|
||||
else()
|
||||
message(FATAL_ERROR "unsupported value of DISPATCH_USE_SANITIZER: ${DISPATCH_USE_SANITIZER}")
|
||||
endif()
|
||||
endif()
|
||||
74
Telegram/ThirdParty/dispatch/cmake/modules/DispatchWindowsSupport.cmake
vendored
Normal file
74
Telegram/ThirdParty/dispatch/cmake/modules/DispatchWindowsSupport.cmake
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
|
||||
function(dispatch_windows_arch_spelling arch var)
|
||||
if(${arch} STREQUAL i686)
|
||||
set(${var} x86 PARENT_SCOPE)
|
||||
elseif(${arch} STREQUAL x86_64 OR ${arch} STREQUAL AMD64)
|
||||
set(${var} x64 PARENT_SCOPE)
|
||||
elseif(${arch} STREQUAL armv7)
|
||||
set(${var} arm PARENT_SCOPE)
|
||||
elseif(${arch} STREQUAL aarch64 OR ${arch} STREQUAL ARM64)
|
||||
set(${var} arm64 PARENT_SCOPE)
|
||||
else()
|
||||
message(FATAL_ERROR "do not know MSVC spelling for ARCH: `${arch}`")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(dispatch_verify_windows_environment_variables)
|
||||
set(VCToolsInstallDir $ENV{VCToolsInstallDir})
|
||||
set(UniversalCRTSdkDir $ENV{UniversalCRTSdkDir})
|
||||
set(UCRTVersion $ENV{UCRTVersion})
|
||||
|
||||
if("${VCToolsInstallDir}" STREQUAL "")
|
||||
message(SEND_ERROR "VCToolsInstallDir environment variable must be set")
|
||||
endif()
|
||||
if("${UniversalCRTSdkDir}" STREQUAL "")
|
||||
message(SEND_ERROR "UniversalCRTSdkDir environment variable must be set")
|
||||
endif()
|
||||
if("${UCRTVersion}" STREQUAL "")
|
||||
message(SEND_ERROR "UCRTVersion environment variable must be set")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(dispatch_windows_include_for_arch arch var)
|
||||
dispatch_verify_windows_environment_variables()
|
||||
|
||||
set(paths
|
||||
"$ENV{VCToolsInstallDir}/include"
|
||||
"$ENV{UniversalCRTSdkDir}/Include/$ENV{UCRTVersion}/ucrt"
|
||||
"$ENV{UniversalCRTSdkDir}/Include/$ENV{UCRTVersion}/shared"
|
||||
"$ENV{UniversalCRTSdkDir}/Include/$ENV{UCRTVersion}/um")
|
||||
set(${var} ${paths} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(dispatch_windows_lib_for_arch arch var)
|
||||
dispatch_verify_windows_environment_variables()
|
||||
dispatch_windows_arch_spelling(${arch} ARCH)
|
||||
|
||||
set(paths)
|
||||
if(${ARCH} STREQUAL x86)
|
||||
list(APPEND paths "$ENV{VCToolsInstallDir}/Lib")
|
||||
else()
|
||||
list(APPEND paths "$ENV{VCToolsInstallDir}/Lib/${ARCH}")
|
||||
endif()
|
||||
list(APPEND paths
|
||||
"$ENV{UniversalCRTSdkDir}/Lib/$ENV{UCRTVersion}/ucrt/${ARCH}"
|
||||
"$ENV{UniversalCRTSdkDir}/Lib/$ENV{UCRTVersion}/um/${ARCH}")
|
||||
set(${var} ${paths} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(dispatch_windows_generate_sdk_vfs_overlay flags)
|
||||
dispatch_verify_windows_environment_variables()
|
||||
|
||||
get_filename_component(VCToolsInstallDir $ENV{VCToolsInstallDir} ABSOLUTE)
|
||||
get_filename_component(UniversalCRTSdkDir $ENV{UniversalCRTSdkDir} ABSOLUTE)
|
||||
set(UCRTVersion $ENV{UCRTVersion})
|
||||
|
||||
# TODO(compnerd) use a target to avoid re-creating this file all the time
|
||||
configure_file("${PROJECT_SOURCE_DIR}/utils/WindowsSDKVFSOverlay.yaml.in"
|
||||
"${PROJECT_BINARY_DIR}/windows-sdk-vfs-overlay.yaml"
|
||||
@ONLY)
|
||||
|
||||
set(${flags}
|
||||
-ivfsoverlay;"${PROJECT_BINARY_DIR}/windows-sdk-vfs-overlay.yaml"
|
||||
PARENT_SCOPE)
|
||||
endfunction()
|
||||
48
Telegram/ThirdParty/dispatch/cmake/modules/FindBlocksRuntime.cmake
vendored
Normal file
48
Telegram/ThirdParty/dispatch/cmake/modules/FindBlocksRuntime.cmake
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
#.rst:
|
||||
# FindBlocksRuntime
|
||||
# -----------------
|
||||
#
|
||||
# Find libBlocksRuntime library and headers.
|
||||
#
|
||||
# The module defines the following variables:
|
||||
#
|
||||
# ##
|
||||
#
|
||||
# BlocksRuntime_FOUND - true if libBlocksRuntime was found
|
||||
# BlocksRuntime_INCLUDE_DIR - include search path
|
||||
# BlocksRuntime_LIBRARIES - libraries to link
|
||||
|
||||
if(BlocksRuntime_INCLUDE_DIR AND BlocksRuntime_LIBRARIES)
|
||||
set(BlocksRuntime_FOUND TRUE)
|
||||
else()
|
||||
find_path(BlocksRuntime_INCLUDE_DIR
|
||||
NAMES
|
||||
Blocks.h
|
||||
HINTS
|
||||
${CMAKE_INSTALL_FULL_INCLUDEDIR})
|
||||
find_library(BlocksRuntime_LIBRARIES
|
||||
NAMES
|
||||
BlocksRuntime libBlocksRuntime
|
||||
HINTS
|
||||
${CMAKE_INSTALL_FULL_LIBDIR})
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(BlocksRuntime
|
||||
REQUIRED_VARS
|
||||
BlocksRuntime_LIBRARIES
|
||||
BlocksRuntime_INCLUDE_DIR)
|
||||
|
||||
mark_as_advanced(BlocksRuntime_LIBRARIES BlocksRuntime_INCLUDE_DIR)
|
||||
endif()
|
||||
|
||||
if(BlocksRuntime_FOUND)
|
||||
if(NOT TARGET BlocksRuntime::BlocksRuntime)
|
||||
add_library(BlocksRuntime::BlocksRuntime UNKNOWN IMPORTED)
|
||||
set_target_properties(BlocksRuntime::BlocksRuntime
|
||||
PROPERTIES
|
||||
IMPORTED_LOCATION
|
||||
${BlocksRuntime_LIBRARIES}
|
||||
INTERFACE_INCLUDE_DIRECTORIES
|
||||
${BlocksRuntime_INCLUDE_DIR})
|
||||
endif()
|
||||
endif()
|
||||
39
Telegram/ThirdParty/dispatch/cmake/modules/FindLibRT.cmake
vendored
Normal file
39
Telegram/ThirdParty/dispatch/cmake/modules/FindLibRT.cmake
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
#.rst:
|
||||
# FindLibRT
|
||||
# ---------
|
||||
#
|
||||
# Find librt library and headers.
|
||||
#
|
||||
# The mdoule defines the following variables:
|
||||
#
|
||||
# ::
|
||||
#
|
||||
# LibRT_FOUND - true if librt was found
|
||||
# LibRT_INCLUDE_DIR - include search path
|
||||
# LibRT_LIBRARIES - libraries to link
|
||||
|
||||
if(UNIX)
|
||||
find_path(LibRT_INCLUDE_DIR
|
||||
NAMES
|
||||
time.h)
|
||||
find_library(LibRT_LIBRARIES rt)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(LibRT
|
||||
REQUIRED_VARS
|
||||
LibRT_LIBRARIES
|
||||
LibRT_INCLUDE_DIR)
|
||||
|
||||
if(LibRT_FOUND)
|
||||
if(NOT TARGET RT::rt)
|
||||
add_library(RT::rt UNKNOWN IMPORTED)
|
||||
set_target_properties(RT::rt
|
||||
PROPERTIES
|
||||
IMPORTED_LOCATION ${LibRT_LIBRARIES}
|
||||
INTERFACE_INCLUDE_DIRECTORIES ${LibRT_INCLUDE_DIR})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
mark_as_advanced(LibRT_LIBRARIES LibRT_INCLUDE_DIR)
|
||||
endif()
|
||||
|
||||
41
Telegram/ThirdParty/dispatch/cmake/modules/SwiftSupport.cmake
vendored
Normal file
41
Telegram/ThirdParty/dispatch/cmake/modules/SwiftSupport.cmake
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
|
||||
# Returns the current achitecture name in a variable
|
||||
#
|
||||
# Usage:
|
||||
# get_swift_host_arch(result_var_name)
|
||||
#
|
||||
# If the current architecture is supported by Swift, sets ${result_var_name}
|
||||
# with the sanitized host architecture name derived from CMAKE_SYSTEM_PROCESSOR.
|
||||
function(get_swift_host_arch result_var_name)
|
||||
if("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86_64")
|
||||
set("${result_var_name}" "x86_64" PARENT_SCOPE)
|
||||
elseif ("${CMAKE_SYSTEM_PROCESSOR}" MATCHES "AArch64|aarch64|arm64|ARM64")
|
||||
if(CMAKE_SYSTEM_NAME MATCHES Darwin)
|
||||
set("${result_var_name}" "arm64" PARENT_SCOPE)
|
||||
else()
|
||||
set("${result_var_name}" "aarch64" PARENT_SCOPE)
|
||||
endif()
|
||||
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "ppc64")
|
||||
set("${result_var_name}" "powerpc64" PARENT_SCOPE)
|
||||
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "ppc64le")
|
||||
set("${result_var_name}" "powerpc64le" PARENT_SCOPE)
|
||||
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "s390x")
|
||||
set("${result_var_name}" "s390x" PARENT_SCOPE)
|
||||
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv6l")
|
||||
set("${result_var_name}" "armv6" PARENT_SCOPE)
|
||||
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv7-a")
|
||||
set("${result_var_name}" "armv7" PARENT_SCOPE)
|
||||
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv7l")
|
||||
set("${result_var_name}" "armv7" PARENT_SCOPE)
|
||||
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "AMD64")
|
||||
set("${result_var_name}" "x86_64" PARENT_SCOPE)
|
||||
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "IA64")
|
||||
set("${result_var_name}" "itanium" PARENT_SCOPE)
|
||||
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "x86")
|
||||
set("${result_var_name}" "i686" PARENT_SCOPE)
|
||||
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "i686")
|
||||
set("${result_var_name}" "i686" PARENT_SCOPE)
|
||||
else()
|
||||
message(FATAL_ERROR "Unrecognized architecture on host system: ${CMAKE_SYSTEM_PROCESSOR}")
|
||||
endif()
|
||||
endfunction()
|
||||
7
Telegram/ThirdParty/dispatch/cmake/modules/dispatchConfig.cmake.in
vendored
Normal file
7
Telegram/ThirdParty/dispatch/cmake/modules/dispatchConfig.cmake.in
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
set(DISPATCH_HAS_SWIFT_SDK_OVERLAY @ENABLE_SWIFT@)
|
||||
|
||||
if(NOT TARGET dispatch)
|
||||
include(@DISPATCH_EXPORTS_FILE@)
|
||||
endif()
|
||||
|
||||
35
Telegram/ThirdParty/dispatch/dispatch/CMakeLists.txt
vendored
Normal file
35
Telegram/ThirdParty/dispatch/dispatch/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,35 @@
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
|
||||
set(DISPATCH_MODULE_MAP ${PROJECT_SOURCE_DIR}/dispatch/darwin/module.modulemap)
|
||||
elseif(BUILD_SHARED_LIBS)
|
||||
set(DISPATCH_MODULE_MAP ${PROJECT_SOURCE_DIR}/dispatch/generic/module.modulemap)
|
||||
else()
|
||||
set(DISPATCH_MODULE_MAP ${PROJECT_SOURCE_DIR}/dispatch/generic_static/module.modulemap)
|
||||
endif()
|
||||
configure_file(dispatch-vfs.yaml.in
|
||||
${CMAKE_BINARY_DIR}/dispatch-vfs-overlay.yaml
|
||||
@ONLY)
|
||||
|
||||
install(FILES
|
||||
base.h
|
||||
block.h
|
||||
data.h
|
||||
dispatch.h
|
||||
group.h
|
||||
introspection.h
|
||||
io.h
|
||||
object.h
|
||||
once.h
|
||||
queue.h
|
||||
semaphore.h
|
||||
source.h
|
||||
time.h
|
||||
DESTINATION
|
||||
"${INSTALL_DISPATCH_HEADERS_DIR}")
|
||||
if(ENABLE_SWIFT)
|
||||
install(FILES
|
||||
${DISPATCH_MODULE_MAP}
|
||||
DESTINATION
|
||||
"${INSTALL_DISPATCH_HEADERS_DIR}")
|
||||
endif()
|
||||
|
||||
326
Telegram/ThirdParty/dispatch/dispatch/base.h
vendored
Normal file
326
Telegram/ThirdParty/dispatch/dispatch/base.h
vendored
Normal file
@@ -0,0 +1,326 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2012 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#ifndef __DISPATCH_BASE__
|
||||
#define __DISPATCH_BASE__
|
||||
|
||||
#ifndef __DISPATCH_INDIRECT__
|
||||
#error "Please #include <dispatch/dispatch.h> instead of this file directly."
|
||||
#endif
|
||||
|
||||
#ifndef __has_builtin
|
||||
#define __has_builtin(x) 0
|
||||
#endif
|
||||
#ifndef __has_include
|
||||
#define __has_include(x) 0
|
||||
#endif
|
||||
#ifndef __has_feature
|
||||
#define __has_feature(x) 0
|
||||
#endif
|
||||
#ifndef __has_attribute
|
||||
#define __has_attribute(x) 0
|
||||
#endif
|
||||
#ifndef __has_extension
|
||||
#define __has_extension(x) 0
|
||||
#endif
|
||||
|
||||
#if __GNUC__
|
||||
#define DISPATCH_NORETURN __attribute__((__noreturn__))
|
||||
#define DISPATCH_NOTHROW __attribute__((__nothrow__))
|
||||
#define DISPATCH_NONNULL1 __attribute__((__nonnull__(1)))
|
||||
#define DISPATCH_NONNULL2 __attribute__((__nonnull__(2)))
|
||||
#define DISPATCH_NONNULL3 __attribute__((__nonnull__(3)))
|
||||
#define DISPATCH_NONNULL4 __attribute__((__nonnull__(4)))
|
||||
#define DISPATCH_NONNULL5 __attribute__((__nonnull__(5)))
|
||||
#define DISPATCH_NONNULL6 __attribute__((__nonnull__(6)))
|
||||
#define DISPATCH_NONNULL7 __attribute__((__nonnull__(7)))
|
||||
#if __clang__ && __clang_major__ < 3
|
||||
// rdar://problem/6857843
|
||||
#define DISPATCH_NONNULL_ALL
|
||||
#else
|
||||
#define DISPATCH_NONNULL_ALL __attribute__((__nonnull__))
|
||||
#endif
|
||||
#define DISPATCH_SENTINEL __attribute__((__sentinel__))
|
||||
#define DISPATCH_PURE __attribute__((__pure__))
|
||||
#define DISPATCH_CONST __attribute__((__const__))
|
||||
#define DISPATCH_WARN_RESULT __attribute__((__warn_unused_result__))
|
||||
#define DISPATCH_MALLOC __attribute__((__malloc__))
|
||||
#define DISPATCH_ALWAYS_INLINE __attribute__((__always_inline__))
|
||||
#define DISPATCH_UNAVAILABLE __attribute__((__unavailable__))
|
||||
#define DISPATCH_UNAVAILABLE_MSG(msg) __attribute__((__unavailable__(msg)))
|
||||
#elif defined(_MSC_VER)
|
||||
#define DISPATCH_NORETURN __declspec(noreturn)
|
||||
#define DISPATCH_NOTHROW __declspec(nothrow)
|
||||
#define DISPATCH_NONNULL1
|
||||
#define DISPATCH_NONNULL2
|
||||
#define DISPATCH_NONNULL3
|
||||
#define DISPATCH_NONNULL4
|
||||
#define DISPATCH_NONNULL5
|
||||
#define DISPATCH_NONNULL6
|
||||
#define DISPATCH_NONNULL7
|
||||
#define DISPATCH_NONNULL_ALL
|
||||
#define DISPATCH_SENTINEL
|
||||
#define DISPATCH_PURE
|
||||
#define DISPATCH_CONST
|
||||
#if (_MSC_VER >= 1700)
|
||||
#define DISPATCH_WARN_RESULT _Check_return_
|
||||
#else
|
||||
#define DISPATCH_WARN_RESULT
|
||||
#endif
|
||||
#define DISPATCH_MALLOC
|
||||
#define DISPATCH_ALWAYS_INLINE __forceinline
|
||||
#define DISPATCH_UNAVAILABLE
|
||||
#define DISPATCH_UNAVAILABLE_MSG(msg)
|
||||
#else
|
||||
/*! @parseOnly */
|
||||
#define DISPATCH_NORETURN
|
||||
/*! @parseOnly */
|
||||
#define DISPATCH_NOTHROW
|
||||
/*! @parseOnly */
|
||||
#define DISPATCH_NONNULL1
|
||||
/*! @parseOnly */
|
||||
#define DISPATCH_NONNULL2
|
||||
/*! @parseOnly */
|
||||
#define DISPATCH_NONNULL3
|
||||
/*! @parseOnly */
|
||||
#define DISPATCH_NONNULL4
|
||||
/*! @parseOnly */
|
||||
#define DISPATCH_NONNULL5
|
||||
/*! @parseOnly */
|
||||
#define DISPATCH_NONNULL6
|
||||
/*! @parseOnly */
|
||||
#define DISPATCH_NONNULL7
|
||||
/*! @parseOnly */
|
||||
#define DISPATCH_NONNULL_ALL
|
||||
/*! @parseOnly */
|
||||
#define DISPATCH_SENTINEL
|
||||
/*! @parseOnly */
|
||||
#define DISPATCH_PURE
|
||||
/*! @parseOnly */
|
||||
#define DISPATCH_CONST
|
||||
/*! @parseOnly */
|
||||
#define DISPATCH_WARN_RESULT
|
||||
/*! @parseOnly */
|
||||
#define DISPATCH_MALLOC
|
||||
/*! @parseOnly */
|
||||
#define DISPATCH_ALWAYS_INLINE
|
||||
/*! @parseOnly */
|
||||
#define DISPATCH_UNAVAILABLE
|
||||
/*! @parseOnly */
|
||||
#define DISPATCH_UNAVAILABLE_MSG(msg)
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
# if __cplusplus >= 201703L
|
||||
# define DISPATCH_FALLTHROUGH [[fallthrough]]
|
||||
# elif __cplusplus >= 201103L
|
||||
# if defined(__clang__)
|
||||
# define DISPATCH_FALLTHROUGH [[clang::fallthrough]]
|
||||
# elif defined(__GNUC__) && __GNUC__ >= 7
|
||||
# define DISPATCH_FALLTHROUGH [[gnu::fallthrough]]
|
||||
# else
|
||||
# define DISPATCH_FALLTHROUGH
|
||||
# endif
|
||||
# else
|
||||
# define DISPATCH_FALLTHROUGH
|
||||
# endif
|
||||
#elif defined(__GNUC__) && __GNUC__ >= 7
|
||||
# define DISPATCH_FALLTHROUGH __attribute__((__fallthrough__))
|
||||
#elif defined(__clang__)
|
||||
# if __has_attribute(fallthrough) && __clang_major__ >= 5
|
||||
# define DISPATCH_FALLTHROUGH __attribute__((__fallthrough__))
|
||||
# else
|
||||
# define DISPATCH_FALLTHROUGH
|
||||
# endif
|
||||
#else
|
||||
# define DISPATCH_FALLTHROUGH
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __linux__
|
||||
#define DISPATCH_LINUX_UNAVAILABLE() \
|
||||
DISPATCH_UNAVAILABLE_MSG( \
|
||||
"This interface is unavailable on linux systems")
|
||||
#else
|
||||
#define DISPATCH_LINUX_UNAVAILABLE()
|
||||
#endif
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#define DISPATCH_FREEBSD_UNAVAILABLE() \
|
||||
DISPATCH_UNAVAILABLE_MSG( \
|
||||
"This interface is unavailable on FreeBSD systems")
|
||||
#else
|
||||
#define DISPATCH_FREEBSD_UNAVAILABLE()
|
||||
#endif
|
||||
|
||||
#ifndef DISPATCH_ALIAS_V2
|
||||
#if TARGET_OS_MAC
|
||||
#define DISPATCH_ALIAS_V2(sym) __asm__("_" #sym "$V2")
|
||||
#else
|
||||
#define DISPATCH_ALIAS_V2(sym)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
#if defined(__DISPATCH_BUILDING_DISPATCH__)
|
||||
#if defined(__cplusplus)
|
||||
#define DISPATCH_EXPORT extern "C" __declspec(dllexport)
|
||||
#else
|
||||
#define DISPATCH_EXPORT extern __declspec(dllexport)
|
||||
#endif
|
||||
#else
|
||||
#if defined(__cplusplus)
|
||||
#define DISPATCH_EXPORT extern "C" __declspec(dllimport)
|
||||
#else
|
||||
#define DISPATCH_EXPORT extern __declspec(dllimport)
|
||||
#endif
|
||||
#endif
|
||||
#elif __GNUC__
|
||||
#define DISPATCH_EXPORT extern __attribute__((visibility("default")))
|
||||
#else
|
||||
#define DISPATCH_EXPORT extern
|
||||
#endif
|
||||
|
||||
#if __GNUC__
|
||||
#define DISPATCH_INLINE static __inline__
|
||||
#else
|
||||
#define DISPATCH_INLINE static inline
|
||||
#endif
|
||||
|
||||
#if __GNUC__
|
||||
#define DISPATCH_EXPECT(x, v) __builtin_expect((x), (v))
|
||||
#define dispatch_compiler_barrier() __asm__ __volatile__("" ::: "memory")
|
||||
#else
|
||||
#define DISPATCH_EXPECT(x, v) (x)
|
||||
#define dispatch_compiler_barrier() do { } while (0)
|
||||
#endif
|
||||
|
||||
#if __has_attribute(not_tail_called)
|
||||
#define DISPATCH_NOT_TAIL_CALLED __attribute__((__not_tail_called__))
|
||||
#else
|
||||
#define DISPATCH_NOT_TAIL_CALLED
|
||||
#endif
|
||||
|
||||
#if __has_builtin(__builtin_assume)
|
||||
#define DISPATCH_COMPILER_CAN_ASSUME(expr) __builtin_assume(expr)
|
||||
#else
|
||||
#define DISPATCH_COMPILER_CAN_ASSUME(expr) ((void)(expr))
|
||||
#endif
|
||||
|
||||
#if __has_attribute(noescape)
|
||||
#define DISPATCH_NOESCAPE __attribute__((__noescape__))
|
||||
#else
|
||||
#define DISPATCH_NOESCAPE
|
||||
#endif
|
||||
|
||||
#if __has_attribute(cold)
|
||||
#define DISPATCH_COLD __attribute__((__cold__))
|
||||
#else
|
||||
#define DISPATCH_COLD
|
||||
#endif
|
||||
|
||||
#if __has_feature(assume_nonnull)
|
||||
#define DISPATCH_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin")
|
||||
#define DISPATCH_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end")
|
||||
#else
|
||||
#define DISPATCH_ASSUME_NONNULL_BEGIN
|
||||
#define DISPATCH_ASSUME_NONNULL_END
|
||||
#endif
|
||||
|
||||
#if !__has_feature(nullability)
|
||||
#ifndef _Nullable
|
||||
#define _Nullable
|
||||
#endif
|
||||
#ifndef _Nonnull
|
||||
#define _Nonnull
|
||||
#endif
|
||||
#ifndef _Null_unspecified
|
||||
#define _Null_unspecified
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef DISPATCH_RETURNS_RETAINED_BLOCK
|
||||
#if __has_attribute(ns_returns_retained)
|
||||
#define DISPATCH_RETURNS_RETAINED_BLOCK __attribute__((__ns_returns_retained__))
|
||||
#else
|
||||
#define DISPATCH_RETURNS_RETAINED_BLOCK
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if __has_feature(objc_fixed_enum) || __has_extension(cxx_strong_enums) || defined(_WIN32)
|
||||
#define DISPATCH_ENUM(name, type, ...) \
|
||||
typedef enum : type { __VA_ARGS__ } name##_t
|
||||
#else
|
||||
#define DISPATCH_ENUM(name, type, ...) \
|
||||
enum { __VA_ARGS__ }; typedef type name##_t
|
||||
#endif
|
||||
|
||||
#if __has_feature(enumerator_attributes)
|
||||
#define DISPATCH_ENUM_API_AVAILABLE(...) API_AVAILABLE(__VA_ARGS__)
|
||||
#define DISPATCH_ENUM_API_DEPRECATED(...) API_DEPRECATED(__VA_ARGS__)
|
||||
#define DISPATCH_ENUM_API_DEPRECATED_WITH_REPLACEMENT(...) \
|
||||
API_DEPRECATED_WITH_REPLACEMENT(__VA_ARGS__)
|
||||
#else
|
||||
#define DISPATCH_ENUM_API_AVAILABLE(...)
|
||||
#define DISPATCH_ENUM_API_DEPRECATED(...)
|
||||
#define DISPATCH_ENUM_API_DEPRECATED_WITH_REPLACEMENT(...)
|
||||
#endif
|
||||
|
||||
#if defined(SWIFT_SDK_OVERLAY_DISPATCH_EPOCH) && \
|
||||
SWIFT_SDK_OVERLAY_DISPATCH_EPOCH >= 2
|
||||
#define DISPATCH_SWIFT3_OVERLAY 1
|
||||
#else
|
||||
#define DISPATCH_SWIFT3_OVERLAY 0
|
||||
#endif // SWIFT_SDK_OVERLAY_DISPATCH_EPOCH >= 2
|
||||
|
||||
#if __has_feature(attribute_availability_swift)
|
||||
#define DISPATCH_SWIFT_UNAVAILABLE(_msg) \
|
||||
__attribute__((__availability__(swift, unavailable, message=_msg)))
|
||||
#else
|
||||
#define DISPATCH_SWIFT_UNAVAILABLE(_msg)
|
||||
#endif
|
||||
|
||||
#if DISPATCH_SWIFT3_OVERLAY
|
||||
#define DISPATCH_SWIFT3_UNAVAILABLE(_msg) DISPATCH_SWIFT_UNAVAILABLE(_msg)
|
||||
#else
|
||||
#define DISPATCH_SWIFT3_UNAVAILABLE(_msg)
|
||||
#endif
|
||||
|
||||
#if __has_attribute(swift_private)
|
||||
#define DISPATCH_REFINED_FOR_SWIFT __attribute__((__swift_private__))
|
||||
#else
|
||||
#define DISPATCH_REFINED_FOR_SWIFT
|
||||
#endif
|
||||
|
||||
#if __has_attribute(swift_name)
|
||||
#define DISPATCH_SWIFT_NAME(_name) __attribute__((__swift_name__(#_name)))
|
||||
#else
|
||||
#define DISPATCH_SWIFT_NAME(_name)
|
||||
#endif
|
||||
|
||||
#ifndef __cplusplus
|
||||
#define DISPATCH_TRANSPARENT_UNION __attribute__((__transparent_union__))
|
||||
#else
|
||||
#define DISPATCH_TRANSPARENT_UNION
|
||||
#endif
|
||||
|
||||
typedef void (*dispatch_function_t)(void *_Nullable);
|
||||
|
||||
#endif /* __DISPATCH_BASE__ */
|
||||
428
Telegram/ThirdParty/dispatch/dispatch/block.h
vendored
Normal file
428
Telegram/ThirdParty/dispatch/dispatch/block.h
vendored
Normal file
@@ -0,0 +1,428 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#ifndef __DISPATCH_BLOCK__
|
||||
#define __DISPATCH_BLOCK__
|
||||
|
||||
#ifndef __DISPATCH_INDIRECT__
|
||||
#error "Please #include <dispatch/dispatch.h> instead of this file directly."
|
||||
#include <dispatch/base.h> // for HeaderDoc
|
||||
#endif
|
||||
|
||||
#ifdef __BLOCKS__
|
||||
|
||||
/*!
|
||||
* @group Dispatch block objects
|
||||
*/
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_BEGIN
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_block_flags_t
|
||||
* Flags to pass to the dispatch_block_create* functions.
|
||||
*
|
||||
* @const DISPATCH_BLOCK_BARRIER
|
||||
* Flag indicating that a dispatch block object should act as a barrier block
|
||||
* when submitted to a DISPATCH_QUEUE_CONCURRENT queue.
|
||||
* See dispatch_barrier_async() for details.
|
||||
* This flag has no effect when the dispatch block object is invoked directly.
|
||||
*
|
||||
* @const DISPATCH_BLOCK_DETACHED
|
||||
* Flag indicating that a dispatch block object should execute disassociated
|
||||
* from current execution context attributes such as os_activity_t
|
||||
* and properties of the current IPC request (if any). With regard to QoS class,
|
||||
* the behavior is the same as for DISPATCH_BLOCK_NO_QOS. If invoked directly,
|
||||
* the block object will remove the other attributes from the calling thread for
|
||||
* the duration of the block body (before applying attributes assigned to the
|
||||
* block object, if any). If submitted to a queue, the block object will be
|
||||
* executed with the attributes of the queue (or any attributes specifically
|
||||
* assigned to the block object).
|
||||
*
|
||||
* @const DISPATCH_BLOCK_ASSIGN_CURRENT
|
||||
* Flag indicating that a dispatch block object should be assigned the execution
|
||||
* context attributes that are current at the time the block object is created.
|
||||
* This applies to attributes such as QOS class, os_activity_t and properties of
|
||||
* the current IPC request (if any). If invoked directly, the block object will
|
||||
* apply these attributes to the calling thread for the duration of the block
|
||||
* body. If the block object is submitted to a queue, this flag replaces the
|
||||
* default behavior of associating the submitted block instance with the
|
||||
* execution context attributes that are current at the time of submission.
|
||||
* If a specific QOS class is assigned with DISPATCH_BLOCK_NO_QOS_CLASS or
|
||||
* dispatch_block_create_with_qos_class(), that QOS class takes precedence over
|
||||
* the QOS class assignment indicated by this flag.
|
||||
*
|
||||
* @const DISPATCH_BLOCK_NO_QOS_CLASS
|
||||
* Flag indicating that a dispatch block object should be not be assigned a QOS
|
||||
* class. If invoked directly, the block object will be executed with the QOS
|
||||
* class of the calling thread. If the block object is submitted to a queue,
|
||||
* this replaces the default behavior of associating the submitted block
|
||||
* instance with the QOS class current at the time of submission.
|
||||
* This flag is ignored if a specific QOS class is assigned with
|
||||
* dispatch_block_create_with_qos_class().
|
||||
*
|
||||
* @const DISPATCH_BLOCK_INHERIT_QOS_CLASS
|
||||
* Flag indicating that execution of a dispatch block object submitted to a
|
||||
* queue should prefer the QOS class assigned to the queue over the QOS class
|
||||
* assigned to the block (resp. associated with the block at the time of
|
||||
* submission). The latter will only be used if the queue in question does not
|
||||
* have an assigned QOS class, as long as doing so does not result in a QOS
|
||||
* class lower than the QOS class inherited from the queue's target queue.
|
||||
* This flag is the default when a dispatch block object is submitted to a queue
|
||||
* for asynchronous execution and has no effect when the dispatch block object
|
||||
* is invoked directly. It is ignored if DISPATCH_BLOCK_ENFORCE_QOS_CLASS is
|
||||
* also passed.
|
||||
*
|
||||
* @const DISPATCH_BLOCK_ENFORCE_QOS_CLASS
|
||||
* Flag indicating that execution of a dispatch block object submitted to a
|
||||
* queue should prefer the QOS class assigned to the block (resp. associated
|
||||
* with the block at the time of submission) over the QOS class assigned to the
|
||||
* queue, as long as doing so will not result in a lower QOS class.
|
||||
* This flag is the default when a dispatch block object is submitted to a queue
|
||||
* for synchronous execution or when the dispatch block object is invoked
|
||||
* directly.
|
||||
*/
|
||||
DISPATCH_ENUM(dispatch_block_flags, unsigned long,
|
||||
DISPATCH_BLOCK_BARRIER
|
||||
DISPATCH_ENUM_API_AVAILABLE(macos(10.10), ios(8.0)) = 0x1,
|
||||
DISPATCH_BLOCK_DETACHED
|
||||
DISPATCH_ENUM_API_AVAILABLE(macos(10.10), ios(8.0)) = 0x2,
|
||||
DISPATCH_BLOCK_ASSIGN_CURRENT
|
||||
DISPATCH_ENUM_API_AVAILABLE(macos(10.10), ios(8.0)) = 0x4,
|
||||
DISPATCH_BLOCK_NO_QOS_CLASS
|
||||
DISPATCH_ENUM_API_AVAILABLE(macos(10.10), ios(8.0)) = 0x8,
|
||||
DISPATCH_BLOCK_INHERIT_QOS_CLASS
|
||||
DISPATCH_ENUM_API_AVAILABLE(macos(10.10), ios(8.0)) = 0x10,
|
||||
DISPATCH_BLOCK_ENFORCE_QOS_CLASS
|
||||
DISPATCH_ENUM_API_AVAILABLE(macos(10.10), ios(8.0)) = 0x20,
|
||||
);
|
||||
|
||||
/*!
|
||||
* @function dispatch_block_create
|
||||
*
|
||||
* @abstract
|
||||
* Create a new dispatch block object on the heap from an existing block and
|
||||
* the given flags.
|
||||
*
|
||||
* @discussion
|
||||
* The provided block is Block_copy'ed to the heap and retained by the newly
|
||||
* created dispatch block object.
|
||||
*
|
||||
* The returned dispatch block object is intended to be submitted to a dispatch
|
||||
* queue with dispatch_async() and related functions, but may also be invoked
|
||||
* directly. Both operations can be performed an arbitrary number of times but
|
||||
* only the first completed execution of a dispatch block object can be waited
|
||||
* on with dispatch_block_wait() or observed with dispatch_block_notify().
|
||||
*
|
||||
* If the returned dispatch block object is submitted to a dispatch queue, the
|
||||
* submitted block instance will be associated with the QOS class current at the
|
||||
* time of submission, unless one of the following flags assigned a specific QOS
|
||||
* class (or no QOS class) at the time of block creation:
|
||||
* - DISPATCH_BLOCK_ASSIGN_CURRENT
|
||||
* - DISPATCH_BLOCK_NO_QOS_CLASS
|
||||
* - DISPATCH_BLOCK_DETACHED
|
||||
* The QOS class the block object will be executed with also depends on the QOS
|
||||
* class assigned to the queue and which of the following flags was specified or
|
||||
* defaulted to:
|
||||
* - DISPATCH_BLOCK_INHERIT_QOS_CLASS (default for asynchronous execution)
|
||||
* - DISPATCH_BLOCK_ENFORCE_QOS_CLASS (default for synchronous execution)
|
||||
* See description of dispatch_block_flags_t for details.
|
||||
*
|
||||
* If the returned dispatch block object is submitted directly to a serial queue
|
||||
* and is configured to execute with a specific QOS class, the system will make
|
||||
* a best effort to apply the necessary QOS overrides to ensure that blocks
|
||||
* submitted earlier to the serial queue are executed at that same QOS class or
|
||||
* higher.
|
||||
*
|
||||
* @param flags
|
||||
* Configuration flags for the block object.
|
||||
* Passing a value that is not a bitwise OR of flags from dispatch_block_flags_t
|
||||
* results in NULL being returned.
|
||||
*
|
||||
* @param block
|
||||
* The block to create the dispatch block object from.
|
||||
*
|
||||
* @result
|
||||
* The newly created dispatch block object, or NULL.
|
||||
* When not building with Objective-C ARC, must be released with a -[release]
|
||||
* message or the Block_release() function.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_RETURNS_RETAINED_BLOCK
|
||||
DISPATCH_WARN_RESULT DISPATCH_NOTHROW
|
||||
dispatch_block_t
|
||||
dispatch_block_create(dispatch_block_flags_t flags, dispatch_block_t block);
|
||||
|
||||
/*!
|
||||
* @function dispatch_block_create_with_qos_class
|
||||
*
|
||||
* @abstract
|
||||
* Create a new dispatch block object on the heap from an existing block and
|
||||
* the given flags, and assign it the specified QOS class and relative priority.
|
||||
*
|
||||
* @discussion
|
||||
* The provided block is Block_copy'ed to the heap and retained by the newly
|
||||
* created dispatch block object.
|
||||
*
|
||||
* The returned dispatch block object is intended to be submitted to a dispatch
|
||||
* queue with dispatch_async() and related functions, but may also be invoked
|
||||
* directly. Both operations can be performed an arbitrary number of times but
|
||||
* only the first completed execution of a dispatch block object can be waited
|
||||
* on with dispatch_block_wait() or observed with dispatch_block_notify().
|
||||
*
|
||||
* If invoked directly, the returned dispatch block object will be executed with
|
||||
* the assigned QOS class as long as that does not result in a lower QOS class
|
||||
* than what is current on the calling thread.
|
||||
*
|
||||
* If the returned dispatch block object is submitted to a dispatch queue, the
|
||||
* QOS class it will be executed with depends on the QOS class assigned to the
|
||||
* block, the QOS class assigned to the queue and which of the following flags
|
||||
* was specified or defaulted to:
|
||||
* - DISPATCH_BLOCK_INHERIT_QOS_CLASS: default for asynchronous execution
|
||||
* - DISPATCH_BLOCK_ENFORCE_QOS_CLASS: default for synchronous execution
|
||||
* See description of dispatch_block_flags_t for details.
|
||||
*
|
||||
* If the returned dispatch block object is submitted directly to a serial queue
|
||||
* and is configured to execute with a specific QOS class, the system will make
|
||||
* a best effort to apply the necessary QOS overrides to ensure that blocks
|
||||
* submitted earlier to the serial queue are executed at that same QOS class or
|
||||
* higher.
|
||||
*
|
||||
* @param flags
|
||||
* Configuration flags for the new block object.
|
||||
* Passing a value that is not a bitwise OR of flags from dispatch_block_flags_t
|
||||
* results in NULL being returned.
|
||||
*
|
||||
* @param qos_class
|
||||
* A QOS class value:
|
||||
* - QOS_CLASS_USER_INTERACTIVE
|
||||
* - QOS_CLASS_USER_INITIATED
|
||||
* - QOS_CLASS_DEFAULT
|
||||
* - QOS_CLASS_UTILITY
|
||||
* - QOS_CLASS_BACKGROUND
|
||||
* - QOS_CLASS_UNSPECIFIED
|
||||
* Passing QOS_CLASS_UNSPECIFIED is equivalent to specifying the
|
||||
* DISPATCH_BLOCK_NO_QOS_CLASS flag. Passing any other value results in NULL
|
||||
* being returned.
|
||||
*
|
||||
* @param relative_priority
|
||||
* A relative priority within the QOS class. This value is a negative
|
||||
* offset from the maximum supported scheduler priority for the given class.
|
||||
* Passing a value greater than zero or less than QOS_MIN_RELATIVE_PRIORITY
|
||||
* results in NULL being returned.
|
||||
*
|
||||
* @param block
|
||||
* The block to create the dispatch block object from.
|
||||
*
|
||||
* @result
|
||||
* The newly created dispatch block object, or NULL.
|
||||
* When not building with Objective-C ARC, must be released with a -[release]
|
||||
* message or the Block_release() function.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL4 DISPATCH_RETURNS_RETAINED_BLOCK
|
||||
DISPATCH_WARN_RESULT DISPATCH_NOTHROW
|
||||
dispatch_block_t
|
||||
dispatch_block_create_with_qos_class(dispatch_block_flags_t flags,
|
||||
dispatch_qos_class_t qos_class, int relative_priority,
|
||||
dispatch_block_t block);
|
||||
|
||||
/*!
|
||||
* @function dispatch_block_perform
|
||||
*
|
||||
* @abstract
|
||||
* Create, synchronously execute and release a dispatch block object from the
|
||||
* specified block and flags.
|
||||
*
|
||||
* @discussion
|
||||
* Behaves identically to the sequence
|
||||
* <code>
|
||||
* dispatch_block_t b = dispatch_block_create(flags, block);
|
||||
* b();
|
||||
* Block_release(b);
|
||||
* </code>
|
||||
* but may be implemented more efficiently internally by not requiring a copy
|
||||
* to the heap of the specified block or the allocation of a new block object.
|
||||
*
|
||||
* @param flags
|
||||
* Configuration flags for the temporary block object.
|
||||
* The result of passing a value that is not a bitwise OR of flags from
|
||||
* dispatch_block_flags_t is undefined.
|
||||
*
|
||||
* @param block
|
||||
* The block to create the temporary block object from.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_block_perform(dispatch_block_flags_t flags,
|
||||
DISPATCH_NOESCAPE dispatch_block_t block);
|
||||
|
||||
/*!
|
||||
* @function dispatch_block_wait
|
||||
*
|
||||
* @abstract
|
||||
* Wait synchronously until execution of the specified dispatch block object has
|
||||
* completed or until the specified timeout has elapsed.
|
||||
*
|
||||
* @discussion
|
||||
* This function will return immediately if execution of the block object has
|
||||
* already completed.
|
||||
*
|
||||
* It is not possible to wait for multiple executions of the same block object
|
||||
* with this interface; use dispatch_group_wait() for that purpose. A single
|
||||
* dispatch block object may either be waited on once and executed once,
|
||||
* or it may be executed any number of times. The behavior of any other
|
||||
* combination is undefined. Submission to a dispatch queue counts as an
|
||||
* execution, even if cancellation (dispatch_block_cancel) means the block's
|
||||
* code never runs.
|
||||
*
|
||||
* The result of calling this function from multiple threads simultaneously
|
||||
* with the same dispatch block object is undefined, but note that doing so
|
||||
* would violate the rules described in the previous paragraph.
|
||||
*
|
||||
* If this function returns indicating that the specified timeout has elapsed,
|
||||
* then that invocation does not count as the one allowed wait.
|
||||
*
|
||||
* If at the time this function is called, the specified dispatch block object
|
||||
* has been submitted directly to a serial queue, the system will make a best
|
||||
* effort to apply the necessary QOS overrides to ensure that the block and any
|
||||
* blocks submitted earlier to that serial queue are executed at the QOS class
|
||||
* (or higher) of the thread calling dispatch_block_wait().
|
||||
*
|
||||
* @param block
|
||||
* The dispatch block object to wait on.
|
||||
* The result of passing NULL or a block object not returned by one of the
|
||||
* dispatch_block_create* functions is undefined.
|
||||
*
|
||||
* @param timeout
|
||||
* When to timeout (see dispatch_time). As a convenience, there are the
|
||||
* DISPATCH_TIME_NOW and DISPATCH_TIME_FOREVER constants.
|
||||
*
|
||||
* @result
|
||||
* Returns zero on success (the dispatch block object completed within the
|
||||
* specified timeout) or non-zero on error (i.e. timed out).
|
||||
*/
|
||||
API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
|
||||
intptr_t
|
||||
dispatch_block_wait(dispatch_block_t block, dispatch_time_t timeout);
|
||||
|
||||
/*!
|
||||
* @function dispatch_block_notify
|
||||
*
|
||||
* @abstract
|
||||
* Schedule a notification block to be submitted to a queue when the execution
|
||||
* of a specified dispatch block object has completed.
|
||||
*
|
||||
* @discussion
|
||||
* This function will submit the notification block immediately if execution of
|
||||
* the observed block object has already completed.
|
||||
*
|
||||
* It is not possible to be notified of multiple executions of the same block
|
||||
* object with this interface, use dispatch_group_notify() for that purpose.
|
||||
*
|
||||
* A single dispatch block object may either be observed one or more times
|
||||
* and executed once, or it may be executed any number of times. The behavior
|
||||
* of any other combination is undefined. Submission to a dispatch queue
|
||||
* counts as an execution, even if cancellation (dispatch_block_cancel) means
|
||||
* the block's code never runs.
|
||||
*
|
||||
* If multiple notification blocks are scheduled for a single block object,
|
||||
* there is no defined order in which the notification blocks will be submitted
|
||||
* to their associated queues.
|
||||
*
|
||||
* @param block
|
||||
* The dispatch block object to observe.
|
||||
* The result of passing NULL or a block object not returned by one of the
|
||||
* dispatch_block_create* functions is undefined.
|
||||
*
|
||||
* @param queue
|
||||
* The queue to which the supplied notification block will be submitted when
|
||||
* the observed block completes.
|
||||
*
|
||||
* @param notification_block
|
||||
* The notification block to submit when the observed block object completes.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_block_notify(dispatch_block_t block, dispatch_queue_t queue,
|
||||
dispatch_block_t notification_block);
|
||||
|
||||
/*!
|
||||
* @function dispatch_block_cancel
|
||||
*
|
||||
* @abstract
|
||||
* Asynchronously cancel the specified dispatch block object.
|
||||
*
|
||||
* @discussion
|
||||
* Cancellation causes any future execution of the dispatch block object to
|
||||
* return immediately, but does not affect any execution of the block object
|
||||
* that is already in progress.
|
||||
*
|
||||
* Release of any resources associated with the block object will be delayed
|
||||
* until execution of the block object is next attempted (or any execution
|
||||
* already in progress completes).
|
||||
*
|
||||
* NOTE: care needs to be taken to ensure that a block object that may be
|
||||
* canceled does not capture any resources that require execution of the
|
||||
* block body in order to be released (e.g. memory allocated with
|
||||
* malloc(3) that the block body calls free(3) on). Such resources will
|
||||
* be leaked if the block body is never executed due to cancellation.
|
||||
*
|
||||
* @param block
|
||||
* The dispatch block object to cancel.
|
||||
* The result of passing NULL or a block object not returned by one of the
|
||||
* dispatch_block_create* functions is undefined.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_block_cancel(dispatch_block_t block);
|
||||
|
||||
/*!
|
||||
* @function dispatch_block_testcancel
|
||||
*
|
||||
* @abstract
|
||||
* Tests whether the given dispatch block object has been canceled.
|
||||
*
|
||||
* @param block
|
||||
* The dispatch block object to test.
|
||||
* The result of passing NULL or a block object not returned by one of the
|
||||
* dispatch_block_create* functions is undefined.
|
||||
*
|
||||
* @result
|
||||
* Non-zero if canceled and zero if not canceled.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_WARN_RESULT DISPATCH_PURE
|
||||
DISPATCH_NOTHROW
|
||||
intptr_t
|
||||
dispatch_block_testcancel(dispatch_block_t block);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_END
|
||||
|
||||
#endif // __BLOCKS__
|
||||
|
||||
#endif // __DISPATCH_BLOCK__
|
||||
9
Telegram/ThirdParty/dispatch/dispatch/darwin/module.modulemap
vendored
Normal file
9
Telegram/ThirdParty/dispatch/dispatch/darwin/module.modulemap
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
module Dispatch [system] [extern_c] {
|
||||
umbrella header "dispatch.h"
|
||||
export *
|
||||
}
|
||||
|
||||
module DispatchIntrospection [system] [extern_c] {
|
||||
header "introspection.h"
|
||||
export *
|
||||
}
|
||||
278
Telegram/ThirdParty/dispatch/dispatch/data.h
vendored
Normal file
278
Telegram/ThirdParty/dispatch/dispatch/data.h
vendored
Normal file
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2013 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#ifndef __DISPATCH_DATA__
|
||||
#define __DISPATCH_DATA__
|
||||
|
||||
#ifndef __DISPATCH_INDIRECT__
|
||||
#error "Please #include <dispatch/dispatch.h> instead of this file directly."
|
||||
#include <dispatch/base.h> // for HeaderDoc
|
||||
#endif
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_BEGIN
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/*! @header
|
||||
* Dispatch data objects describe contiguous or sparse regions of memory that
|
||||
* may be managed by the system or by the application.
|
||||
* Dispatch data objects are immutable, any direct access to memory regions
|
||||
* represented by dispatch objects must not modify that memory.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_data_t
|
||||
* A dispatch object representing memory regions.
|
||||
*/
|
||||
DISPATCH_DATA_DECL(dispatch_data);
|
||||
|
||||
/*!
|
||||
* @var dispatch_data_empty
|
||||
* @discussion The singleton dispatch data object representing a zero-length
|
||||
* memory region.
|
||||
*/
|
||||
#define dispatch_data_empty \
|
||||
DISPATCH_GLOBAL_OBJECT(dispatch_data_t, _dispatch_data_empty)
|
||||
API_AVAILABLE(macos(10.7), ios(5.0))
|
||||
DISPATCH_EXPORT struct dispatch_data_s _dispatch_data_empty;
|
||||
|
||||
/*!
|
||||
* @const DISPATCH_DATA_DESTRUCTOR_DEFAULT
|
||||
* @discussion The default destructor for dispatch data objects.
|
||||
* Used at data object creation to indicate that the supplied buffer should
|
||||
* be copied into internal storage managed by the system.
|
||||
*/
|
||||
#define DISPATCH_DATA_DESTRUCTOR_DEFAULT NULL
|
||||
|
||||
#ifdef __BLOCKS__
|
||||
/*! @parseOnly */
|
||||
#define DISPATCH_DATA_DESTRUCTOR_TYPE_DECL(name) \
|
||||
DISPATCH_EXPORT const dispatch_block_t _dispatch_data_destructor_##name
|
||||
#else
|
||||
#define DISPATCH_DATA_DESTRUCTOR_TYPE_DECL(name) \
|
||||
DISPATCH_EXPORT const dispatch_function_t \
|
||||
_dispatch_data_destructor_##name
|
||||
#endif /* __BLOCKS__ */
|
||||
|
||||
/*!
|
||||
* @const DISPATCH_DATA_DESTRUCTOR_FREE
|
||||
* @discussion The destructor for dispatch data objects created from a malloc'd
|
||||
* buffer. Used at data object creation to indicate that the supplied buffer
|
||||
* was allocated by the malloc() family and should be destroyed with free(3).
|
||||
*/
|
||||
#define DISPATCH_DATA_DESTRUCTOR_FREE (_dispatch_data_destructor_free)
|
||||
API_AVAILABLE(macos(10.7), ios(5.0))
|
||||
DISPATCH_DATA_DESTRUCTOR_TYPE_DECL(free);
|
||||
|
||||
/*!
|
||||
* @const DISPATCH_DATA_DESTRUCTOR_MUNMAP
|
||||
* @discussion The destructor for dispatch data objects that have been created
|
||||
* from buffers that require deallocation with munmap(2).
|
||||
*/
|
||||
#define DISPATCH_DATA_DESTRUCTOR_MUNMAP (_dispatch_data_destructor_munmap)
|
||||
API_AVAILABLE(macos(10.9), ios(7.0))
|
||||
DISPATCH_DATA_DESTRUCTOR_TYPE_DECL(munmap);
|
||||
|
||||
#ifdef __BLOCKS__
|
||||
/*!
|
||||
* @function dispatch_data_create
|
||||
* Creates a dispatch data object from the given contiguous buffer of memory. If
|
||||
* a non-default destructor is provided, ownership of the buffer remains with
|
||||
* the caller (i.e. the bytes will not be copied). The last release of the data
|
||||
* object will result in the invocation of the specified destructor on the
|
||||
* specified queue to free the buffer.
|
||||
*
|
||||
* If the DISPATCH_DATA_DESTRUCTOR_FREE destructor is provided the buffer will
|
||||
* be freed via free(3) and the queue argument ignored.
|
||||
*
|
||||
* If the DISPATCH_DATA_DESTRUCTOR_DEFAULT destructor is provided, data object
|
||||
* creation will copy the buffer into internal memory managed by the system.
|
||||
*
|
||||
* @param buffer A contiguous buffer of data.
|
||||
* @param size The size of the contiguous buffer of data.
|
||||
* @param queue The queue to which the destructor should be submitted.
|
||||
* @param destructor The destructor responsible for freeing the data when it
|
||||
* is no longer needed.
|
||||
* @result A newly created dispatch data object.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.7), ios(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT DISPATCH_NOTHROW
|
||||
dispatch_data_t
|
||||
dispatch_data_create(const void *buffer,
|
||||
size_t size,
|
||||
dispatch_queue_t _Nullable queue,
|
||||
dispatch_block_t _Nullable destructor);
|
||||
#endif /* __BLOCKS__ */
|
||||
|
||||
/*!
|
||||
* @function dispatch_data_get_size
|
||||
* Returns the logical size of the memory region(s) represented by the specified
|
||||
* dispatch data object.
|
||||
*
|
||||
* @param data The dispatch data object to query.
|
||||
* @result The number of bytes represented by the data object.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.7), ios(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_PURE DISPATCH_NONNULL1 DISPATCH_NOTHROW
|
||||
size_t
|
||||
dispatch_data_get_size(dispatch_data_t data);
|
||||
|
||||
/*!
|
||||
* @function dispatch_data_create_map
|
||||
* Maps the memory represented by the specified dispatch data object as a single
|
||||
* contiguous memory region and returns a new data object representing it.
|
||||
* If non-NULL references to a pointer and a size variable are provided, they
|
||||
* are filled with the location and extent of that region. These allow direct
|
||||
* read access to the represented memory, but are only valid until the returned
|
||||
* object is released. Under ARC, if that object is held in a variable with
|
||||
* automatic storage, care needs to be taken to ensure that it is not released
|
||||
* by the compiler before memory access via the pointer has been completed.
|
||||
*
|
||||
* @param data The dispatch data object to map.
|
||||
* @param buffer_ptr A pointer to a pointer variable to be filled with the
|
||||
* location of the mapped contiguous memory region, or
|
||||
* NULL.
|
||||
* @param size_ptr A pointer to a size_t variable to be filled with the
|
||||
* size of the mapped contiguous memory region, or NULL.
|
||||
* @result A newly created dispatch data object.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.7), ios(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_RETURNS_RETAINED
|
||||
DISPATCH_WARN_RESULT DISPATCH_NOTHROW
|
||||
dispatch_data_t
|
||||
dispatch_data_create_map(dispatch_data_t data,
|
||||
const void *_Nullable *_Nullable buffer_ptr,
|
||||
size_t *_Nullable size_ptr);
|
||||
|
||||
/*!
|
||||
* @function dispatch_data_create_concat
|
||||
* Returns a new dispatch data object representing the concatenation of the
|
||||
* specified data objects. Those objects may be released by the application
|
||||
* after the call returns (however, the system might not deallocate the memory
|
||||
* region(s) described by them until the newly created object has also been
|
||||
* released).
|
||||
*
|
||||
* @param data1 The data object representing the region(s) of memory to place
|
||||
* at the beginning of the newly created object.
|
||||
* @param data2 The data object representing the region(s) of memory to place
|
||||
* at the end of the newly created object.
|
||||
* @result A newly created object representing the concatenation of the
|
||||
* data1 and data2 objects.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.7), ios(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_RETURNS_RETAINED
|
||||
DISPATCH_WARN_RESULT DISPATCH_NOTHROW
|
||||
dispatch_data_t
|
||||
dispatch_data_create_concat(dispatch_data_t data1, dispatch_data_t data2);
|
||||
|
||||
/*!
|
||||
* @function dispatch_data_create_subrange
|
||||
* Returns a new dispatch data object representing a subrange of the specified
|
||||
* data object, which may be released by the application after the call returns
|
||||
* (however, the system might not deallocate the memory region(s) described by
|
||||
* that object until the newly created object has also been released).
|
||||
*
|
||||
* @param data The data object representing the region(s) of memory to
|
||||
* create a subrange of.
|
||||
* @param offset The offset into the data object where the subrange
|
||||
* starts.
|
||||
* @param length The length of the range.
|
||||
* @result A newly created object representing the specified
|
||||
* subrange of the data object.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.7), ios(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_RETURNS_RETAINED
|
||||
DISPATCH_WARN_RESULT DISPATCH_NOTHROW
|
||||
dispatch_data_t
|
||||
dispatch_data_create_subrange(dispatch_data_t data,
|
||||
size_t offset,
|
||||
size_t length);
|
||||
|
||||
#ifdef __BLOCKS__
|
||||
/*!
|
||||
* @typedef dispatch_data_applier_t
|
||||
* A block to be invoked for every contiguous memory region in a data object.
|
||||
*
|
||||
* @param region A data object representing the current region.
|
||||
* @param offset The logical offset of the current region to the start
|
||||
* of the data object.
|
||||
* @param buffer The location of the memory for the current region.
|
||||
* @param size The size of the memory for the current region.
|
||||
* @result A Boolean indicating whether traversal should continue.
|
||||
*/
|
||||
typedef bool (^dispatch_data_applier_t)(dispatch_data_t region,
|
||||
size_t offset,
|
||||
const void *buffer,
|
||||
size_t size);
|
||||
|
||||
/*!
|
||||
* @function dispatch_data_apply
|
||||
* Traverse the memory regions represented by the specified dispatch data object
|
||||
* in logical order and invoke the specified block once for every contiguous
|
||||
* memory region encountered.
|
||||
*
|
||||
* Each invocation of the block is passed a data object representing the current
|
||||
* region and its logical offset, along with the memory location and extent of
|
||||
* the region. These allow direct read access to the memory region, but are only
|
||||
* valid until the passed-in region object is released. Note that the region
|
||||
* object is released by the system when the block returns, it is the
|
||||
* responsibility of the application to retain it if the region object or the
|
||||
* associated memory location are needed after the block returns.
|
||||
*
|
||||
* @param data The data object to traverse.
|
||||
* @param applier The block to be invoked for every contiguous memory
|
||||
* region in the data object.
|
||||
* @result A Boolean indicating whether traversal completed
|
||||
* successfully.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.7), ios(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
bool
|
||||
dispatch_data_apply(dispatch_data_t data,
|
||||
DISPATCH_NOESCAPE dispatch_data_applier_t applier);
|
||||
#endif /* __BLOCKS__ */
|
||||
|
||||
/*!
|
||||
* @function dispatch_data_copy_region
|
||||
* Finds the contiguous memory region containing the specified location among
|
||||
* the regions represented by the specified object and returns a copy of the
|
||||
* internal dispatch data object representing that region along with its logical
|
||||
* offset in the specified object.
|
||||
*
|
||||
* @param data The dispatch data object to query.
|
||||
* @param location The logical position in the data object to query.
|
||||
* @param offset_ptr A pointer to a size_t variable to be filled with the
|
||||
* logical offset of the returned region object to the
|
||||
* start of the queried data object.
|
||||
* @result A newly created dispatch data object.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.7), ios(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_RETURNS_RETAINED
|
||||
DISPATCH_WARN_RESULT DISPATCH_NOTHROW
|
||||
dispatch_data_t
|
||||
dispatch_data_copy_region(dispatch_data_t data,
|
||||
size_t location,
|
||||
size_t *offset_ptr);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_END
|
||||
|
||||
#endif /* __DISPATCH_DATA__ */
|
||||
11
Telegram/ThirdParty/dispatch/dispatch/dispatch-vfs.yaml.in
vendored
Normal file
11
Telegram/ThirdParty/dispatch/dispatch/dispatch-vfs.yaml.in
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
version: 0
|
||||
case-sensitive: false
|
||||
use-external-names: false
|
||||
roots:
|
||||
- name: "@CMAKE_CURRENT_SOURCE_DIR@"
|
||||
type: directory
|
||||
contents:
|
||||
- name: module.modulemap
|
||||
type: file
|
||||
external-contents: "@DISPATCH_MODULE_MAP@"
|
||||
80
Telegram/ThirdParty/dispatch/dispatch/dispatch.h
vendored
Normal file
80
Telegram/ThirdParty/dispatch/dispatch/dispatch.h
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2013 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#ifndef __DISPATCH_PUBLIC__
|
||||
#define __DISPATCH_PUBLIC__
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <Availability.h>
|
||||
#include <os/availability.h>
|
||||
#include <TargetConditionals.h>
|
||||
#include <os/base.h>
|
||||
#elif defined(_WIN32)
|
||||
#include <os/generic_win_base.h>
|
||||
#elif defined(__unix__)
|
||||
#include <os/generic_unix_base.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#if defined(_WIN32)
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#if (defined(__linux__) || defined(__FreeBSD__)) && defined(__has_feature)
|
||||
#if __has_feature(modules)
|
||||
#if !defined(__arm__)
|
||||
#include <stdio.h> // for off_t (to match Glibc.modulemap)
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define DISPATCH_API_VERSION 20180109
|
||||
|
||||
#ifndef __DISPATCH_BUILDING_DISPATCH__
|
||||
#ifndef __DISPATCH_INDIRECT__
|
||||
#define __DISPATCH_INDIRECT__
|
||||
#endif
|
||||
|
||||
#include <os/object.h>
|
||||
#include <dispatch/base.h>
|
||||
#include <dispatch/time.h>
|
||||
#include <dispatch/object.h>
|
||||
#include <dispatch/queue.h>
|
||||
#include <dispatch/block.h>
|
||||
#include <dispatch/source.h>
|
||||
#include <dispatch/group.h>
|
||||
#include <dispatch/semaphore.h>
|
||||
#include <dispatch/once.h>
|
||||
#include <dispatch/data.h>
|
||||
#include <dispatch/io.h>
|
||||
|
||||
#undef __DISPATCH_INDIRECT__
|
||||
#endif /* !__DISPATCH_BUILDING_DISPATCH__ */
|
||||
|
||||
#endif /* __DISPATCH_PUBLIC__ */
|
||||
18
Telegram/ThirdParty/dispatch/dispatch/generic/module.modulemap
vendored
Normal file
18
Telegram/ThirdParty/dispatch/dispatch/generic/module.modulemap
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
module Dispatch {
|
||||
requires blocks
|
||||
export *
|
||||
link "dispatch"
|
||||
link "BlocksRuntime"
|
||||
}
|
||||
|
||||
module DispatchIntrospection [system] [extern_c] {
|
||||
header "introspection.h"
|
||||
export *
|
||||
}
|
||||
|
||||
module CDispatch [system] [extern_c] {
|
||||
umbrella header "dispatch.h"
|
||||
export *
|
||||
requires blocks
|
||||
link "dispatch"
|
||||
}
|
||||
19
Telegram/ThirdParty/dispatch/dispatch/generic_static/module.modulemap
vendored
Normal file
19
Telegram/ThirdParty/dispatch/dispatch/generic_static/module.modulemap
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
module Dispatch {
|
||||
requires blocks
|
||||
export *
|
||||
link "dispatch"
|
||||
link "BlocksRuntime"
|
||||
link "DispatchStubs"
|
||||
}
|
||||
|
||||
module DispatchIntrospection [system] [extern_c] {
|
||||
header "introspection.h"
|
||||
export *
|
||||
}
|
||||
|
||||
module CDispatch [system] [extern_c] {
|
||||
umbrella header "dispatch.h"
|
||||
export *
|
||||
requires blocks
|
||||
link "dispatch"
|
||||
}
|
||||
279
Telegram/ThirdParty/dispatch/dispatch/group.h
vendored
Normal file
279
Telegram/ThirdParty/dispatch/dispatch/group.h
vendored
Normal file
@@ -0,0 +1,279 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2013 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#ifndef __DISPATCH_GROUP__
|
||||
#define __DISPATCH_GROUP__
|
||||
|
||||
#ifndef __DISPATCH_INDIRECT__
|
||||
#error "Please #include <dispatch/dispatch.h> instead of this file directly."
|
||||
#include <dispatch/base.h> // for HeaderDoc
|
||||
#endif
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_group_t
|
||||
* @abstract
|
||||
* A group of blocks submitted to queues for asynchronous invocation.
|
||||
*/
|
||||
DISPATCH_DECL(dispatch_group);
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/*!
|
||||
* @function dispatch_group_create
|
||||
*
|
||||
* @abstract
|
||||
* Creates new group with which blocks may be associated.
|
||||
*
|
||||
* @discussion
|
||||
* This function creates a new group with which blocks may be associated.
|
||||
* The dispatch group may be used to wait for the completion of the blocks it
|
||||
* references. The group object memory is freed with dispatch_release().
|
||||
*
|
||||
* @result
|
||||
* The newly created group, or NULL on failure.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
|
||||
DISPATCH_NOTHROW
|
||||
dispatch_group_t
|
||||
dispatch_group_create(void);
|
||||
|
||||
/*!
|
||||
* @function dispatch_group_async
|
||||
*
|
||||
* @abstract
|
||||
* Submits a block to a dispatch queue and associates the block with the given
|
||||
* dispatch group.
|
||||
*
|
||||
* @discussion
|
||||
* Submits a block to a dispatch queue and associates the block with the given
|
||||
* dispatch group. The dispatch group may be used to wait for the completion
|
||||
* of the blocks it references.
|
||||
*
|
||||
* @param group
|
||||
* A dispatch group to associate with the submitted block.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @param queue
|
||||
* The dispatch queue to which the block will be submitted for asynchronous
|
||||
* invocation.
|
||||
*
|
||||
* @param block
|
||||
* The block to perform asynchronously.
|
||||
*/
|
||||
#ifdef __BLOCKS__
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_group_async(dispatch_group_t group,
|
||||
dispatch_queue_t queue,
|
||||
dispatch_block_t block);
|
||||
#endif /* __BLOCKS__ */
|
||||
|
||||
/*!
|
||||
* @function dispatch_group_async_f
|
||||
*
|
||||
* @abstract
|
||||
* Submits a function to a dispatch queue and associates the block with the
|
||||
* given dispatch group.
|
||||
*
|
||||
* @discussion
|
||||
* See dispatch_group_async() for details.
|
||||
*
|
||||
* @param group
|
||||
* A dispatch group to associate with the submitted function.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @param queue
|
||||
* The dispatch queue to which the function will be submitted for asynchronous
|
||||
* invocation.
|
||||
*
|
||||
* @param context
|
||||
* The application-defined context parameter to pass to the function.
|
||||
*
|
||||
* @param work
|
||||
* The application-defined function to invoke on the target queue. The first
|
||||
* parameter passed to this function is the context provided to
|
||||
* dispatch_group_async_f().
|
||||
*/
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL2 DISPATCH_NONNULL4
|
||||
DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_group_async_f(dispatch_group_t group,
|
||||
dispatch_queue_t queue,
|
||||
void *_Nullable context,
|
||||
dispatch_function_t work);
|
||||
|
||||
/*!
|
||||
* @function dispatch_group_wait
|
||||
*
|
||||
* @abstract
|
||||
* Wait synchronously until all the blocks associated with a group have
|
||||
* completed or until the specified timeout has elapsed.
|
||||
*
|
||||
* @discussion
|
||||
* This function waits for the completion of the blocks associated with the
|
||||
* given dispatch group, and returns after all blocks have completed or when
|
||||
* the specified timeout has elapsed.
|
||||
*
|
||||
* This function will return immediately if there are no blocks associated
|
||||
* with the dispatch group (i.e. the group is empty).
|
||||
*
|
||||
* The result of calling this function from multiple threads simultaneously
|
||||
* with the same dispatch group is undefined.
|
||||
*
|
||||
* After the successful return of this function, the dispatch group is empty.
|
||||
* It may either be released with dispatch_release() or re-used for additional
|
||||
* blocks. See dispatch_group_async() for more information.
|
||||
*
|
||||
* @param group
|
||||
* The dispatch group to wait on.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @param timeout
|
||||
* When to timeout (see dispatch_time). As a convenience, there are the
|
||||
* DISPATCH_TIME_NOW and DISPATCH_TIME_FOREVER constants.
|
||||
*
|
||||
* @result
|
||||
* Returns zero on success (all blocks associated with the group completed
|
||||
* within the specified timeout) or non-zero on error (i.e. timed out).
|
||||
*/
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
intptr_t
|
||||
dispatch_group_wait(dispatch_group_t group, dispatch_time_t timeout);
|
||||
|
||||
/*!
|
||||
* @function dispatch_group_notify
|
||||
*
|
||||
* @abstract
|
||||
* Schedule a block to be submitted to a queue when all the blocks associated
|
||||
* with a group have completed.
|
||||
*
|
||||
* @discussion
|
||||
* This function schedules a notification block to be submitted to the specified
|
||||
* queue once all blocks associated with the dispatch group have completed.
|
||||
*
|
||||
* If no blocks are associated with the dispatch group (i.e. the group is empty)
|
||||
* then the notification block will be submitted immediately.
|
||||
*
|
||||
* The group will be empty at the time the notification block is submitted to
|
||||
* the target queue. The group may either be released with dispatch_release()
|
||||
* or reused for additional operations.
|
||||
* See dispatch_group_async() for more information.
|
||||
*
|
||||
* @param group
|
||||
* The dispatch group to observe.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @param queue
|
||||
* The queue to which the supplied block will be submitted when the group
|
||||
* completes.
|
||||
*
|
||||
* @param block
|
||||
* The block to submit when the group completes.
|
||||
*/
|
||||
#ifdef __BLOCKS__
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_group_notify(dispatch_group_t group,
|
||||
dispatch_queue_t queue,
|
||||
dispatch_block_t block);
|
||||
#endif /* __BLOCKS__ */
|
||||
|
||||
/*!
|
||||
* @function dispatch_group_notify_f
|
||||
*
|
||||
* @abstract
|
||||
* Schedule a function to be submitted to a queue when all the blocks
|
||||
* associated with a group have completed.
|
||||
*
|
||||
* @discussion
|
||||
* See dispatch_group_notify() for details.
|
||||
*
|
||||
* @param group
|
||||
* The dispatch group to observe.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @param context
|
||||
* The application-defined context parameter to pass to the function.
|
||||
*
|
||||
* @param work
|
||||
* The application-defined function to invoke on the target queue. The first
|
||||
* parameter passed to this function is the context provided to
|
||||
* dispatch_group_notify_f().
|
||||
*/
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL2 DISPATCH_NONNULL4
|
||||
DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_group_notify_f(dispatch_group_t group,
|
||||
dispatch_queue_t queue,
|
||||
void *_Nullable context,
|
||||
dispatch_function_t work);
|
||||
|
||||
/*!
|
||||
* @function dispatch_group_enter
|
||||
*
|
||||
* @abstract
|
||||
* Manually indicate a block has entered the group
|
||||
*
|
||||
* @discussion
|
||||
* Calling this function indicates another block has joined the group through
|
||||
* a means other than dispatch_group_async(). Calls to this function must be
|
||||
* balanced with dispatch_group_leave().
|
||||
*
|
||||
* @param group
|
||||
* The dispatch group to update.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_group_enter(dispatch_group_t group);
|
||||
|
||||
/*!
|
||||
* @function dispatch_group_leave
|
||||
*
|
||||
* @abstract
|
||||
* Manually indicate a block in the group has completed
|
||||
*
|
||||
* @discussion
|
||||
* Calling this function indicates block has completed and left the dispatch
|
||||
* group by a means other than dispatch_group_async().
|
||||
*
|
||||
* @param group
|
||||
* The dispatch group to update.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_group_leave(dispatch_group_t group);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_END
|
||||
|
||||
#endif /* __DISPATCH_GROUP__ */
|
||||
188
Telegram/ThirdParty/dispatch/dispatch/introspection.h
vendored
Normal file
188
Telegram/ThirdParty/dispatch/dispatch/introspection.h
vendored
Normal file
@@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#ifndef __DISPATCH_INTROSPECTION__
|
||||
#define __DISPATCH_INTROSPECTION__
|
||||
|
||||
#include <dispatch/dispatch.h>
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*!
|
||||
* @header
|
||||
*
|
||||
* @abstract
|
||||
* Interposable introspection hooks for libdispatch.
|
||||
*
|
||||
* @discussion
|
||||
* These hooks are only available in the introspection version of the library,
|
||||
* loaded by running a process with the environment variable
|
||||
* DYLD_LIBRARY_PATH=/usr/lib/system/introspection
|
||||
*/
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/*!
|
||||
* @function dispatch_introspection_hook_queue_create
|
||||
*
|
||||
* @abstract
|
||||
* Interposable hook function called when a dispatch queue was created.
|
||||
*
|
||||
* @param queue
|
||||
* The newly created dispatch queue.
|
||||
*/
|
||||
|
||||
API_AVAILABLE(macos(10.9), ios(7.0))
|
||||
DISPATCH_EXPORT
|
||||
void
|
||||
dispatch_introspection_hook_queue_create(dispatch_queue_t queue);
|
||||
|
||||
/*!
|
||||
* @function dispatch_introspection_hook_queue_destroy
|
||||
*
|
||||
* @abstract
|
||||
* Interposable hook function called when a dispatch queue is about to be
|
||||
* destroyed.
|
||||
*
|
||||
* @param queue
|
||||
* The dispatch queue about to be destroyed.
|
||||
*/
|
||||
|
||||
API_AVAILABLE(macos(10.9), ios(7.0))
|
||||
DISPATCH_EXPORT
|
||||
void
|
||||
dispatch_introspection_hook_queue_destroy(dispatch_queue_t queue);
|
||||
|
||||
/*!
|
||||
* @function dispatch_introspection_hook_queue_item_enqueue
|
||||
*
|
||||
* @abstract
|
||||
* Interposable hook function called when an item is about to be enqueued onto
|
||||
* a dispatch queue.
|
||||
*
|
||||
* @param queue
|
||||
* The dispatch queue enqueued onto.
|
||||
*
|
||||
* @param item
|
||||
* The object about to be enqueued.
|
||||
*/
|
||||
|
||||
API_AVAILABLE(macos(10.9), ios(7.0))
|
||||
DISPATCH_EXPORT
|
||||
void
|
||||
dispatch_introspection_hook_queue_item_enqueue(dispatch_queue_t queue,
|
||||
dispatch_object_t item);
|
||||
|
||||
/*!
|
||||
* @function dispatch_introspection_hook_queue_item_dequeue
|
||||
*
|
||||
* @abstract
|
||||
* Interposable hook function called when an item was dequeued from a dispatch
|
||||
* queue.
|
||||
*
|
||||
* @param queue
|
||||
* The dispatch queue dequeued from.
|
||||
*
|
||||
* @param item
|
||||
* The dequeued object.
|
||||
*/
|
||||
|
||||
API_AVAILABLE(macos(10.9), ios(7.0))
|
||||
DISPATCH_EXPORT
|
||||
void
|
||||
dispatch_introspection_hook_queue_item_dequeue(dispatch_queue_t queue,
|
||||
dispatch_object_t item);
|
||||
|
||||
/*!
|
||||
* @function dispatch_introspection_hook_queue_item_complete
|
||||
*
|
||||
* @abstract
|
||||
* Interposable hook function called when an item previously dequeued from a
|
||||
* dispatch queue has completed processing.
|
||||
*
|
||||
* @discussion
|
||||
* The object pointer value passed to this function must be treated as a value
|
||||
* only. It is intended solely for matching up with an earlier call to a
|
||||
* dequeue hook function and must NOT be dereferenced.
|
||||
*
|
||||
* @param item
|
||||
* Opaque dentifier for completed item. Must NOT be dereferenced.
|
||||
*/
|
||||
|
||||
API_AVAILABLE(macos(10.10), ios(7.1))
|
||||
DISPATCH_EXPORT
|
||||
void
|
||||
dispatch_introspection_hook_queue_item_complete(dispatch_object_t item);
|
||||
|
||||
/*!
|
||||
* @function dispatch_introspection_hook_queue_callout_begin
|
||||
*
|
||||
* @abstract
|
||||
* Interposable hook function called when a client function is about to be
|
||||
* called out to on a dispatch queue.
|
||||
*
|
||||
* @param queue
|
||||
* The dispatch queue the callout is performed on.
|
||||
*
|
||||
* @param context
|
||||
* The context parameter passed to the function. For a callout to a block,
|
||||
* this is a pointer to the block object.
|
||||
*
|
||||
* @param function
|
||||
* The client function about to be called out to. For a callout to a block,
|
||||
* this is the block object's invoke function.
|
||||
*/
|
||||
|
||||
API_AVAILABLE(macos(10.9), ios(7.0))
|
||||
DISPATCH_EXPORT
|
||||
void
|
||||
dispatch_introspection_hook_queue_callout_begin(dispatch_queue_t queue,
|
||||
void *_Nullable context, dispatch_function_t function);
|
||||
|
||||
/*!
|
||||
* @function dispatch_introspection_hook_queue_callout_end
|
||||
*
|
||||
* @abstract
|
||||
* Interposable hook function called after a client function has returned from
|
||||
* a callout on a dispatch queue.
|
||||
*
|
||||
* @param queue
|
||||
* The dispatch queue the callout was performed on.
|
||||
*
|
||||
* @param context
|
||||
* The context parameter passed to the function. For a callout to a block,
|
||||
* this is a pointer to the block object.
|
||||
*
|
||||
* @param function
|
||||
* The client function that was called out to. For a callout to a block,
|
||||
* this is the block object's invoke function.
|
||||
*/
|
||||
|
||||
API_AVAILABLE(macos(10.9), ios(7.0))
|
||||
DISPATCH_EXPORT
|
||||
void
|
||||
dispatch_introspection_hook_queue_callout_end(dispatch_queue_t queue,
|
||||
void *_Nullable context, dispatch_function_t function);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_END
|
||||
|
||||
#endif /* __DISPATCH_INTROSPECTION__ */
|
||||
597
Telegram/ThirdParty/dispatch/dispatch/io.h
vendored
Normal file
597
Telegram/ThirdParty/dispatch/dispatch/io.h
vendored
Normal file
@@ -0,0 +1,597 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2013 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#ifndef __DISPATCH_IO__
|
||||
#define __DISPATCH_IO__
|
||||
|
||||
#ifndef __DISPATCH_INDIRECT__
|
||||
#error "Please #include <dispatch/dispatch.h> instead of this file directly."
|
||||
#include <dispatch/base.h> // for HeaderDoc
|
||||
#endif
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_BEGIN
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/*! @header
|
||||
* Dispatch I/O provides both stream and random access asynchronous read and
|
||||
* write operations on file descriptors. One or more dispatch I/O channels may
|
||||
* be created from a file descriptor as either the DISPATCH_IO_STREAM type or
|
||||
* DISPATCH_IO_RANDOM type. Once a channel has been created the application may
|
||||
* schedule asynchronous read and write operations.
|
||||
*
|
||||
* The application may set policies on the dispatch I/O channel to indicate the
|
||||
* desired frequency of I/O handlers for long-running operations.
|
||||
*
|
||||
* Dispatch I/O also provides a memory management model for I/O buffers that
|
||||
* avoids unnecessary copying of data when pipelined between channels. Dispatch
|
||||
* I/O monitors the overall memory pressure and I/O access patterns for the
|
||||
* application to optimize resource utilization.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_fd_t
|
||||
* Native file descriptor type for the platform.
|
||||
*/
|
||||
#if defined(_WIN32)
|
||||
typedef intptr_t dispatch_fd_t;
|
||||
#else
|
||||
typedef int dispatch_fd_t;
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @functiongroup Dispatch I/O Convenience API
|
||||
* Convenience wrappers around the dispatch I/O channel API, with simpler
|
||||
* callback handler semantics and no explicit management of channel objects.
|
||||
* File descriptors passed to the convenience API are treated as streams, and
|
||||
* scheduling multiple operations on one file descriptor via the convenience API
|
||||
* may incur more overhead than by using the dispatch I/O channel API directly.
|
||||
*/
|
||||
|
||||
#ifdef __BLOCKS__
|
||||
/*!
|
||||
* @function dispatch_read
|
||||
* Schedule a read operation for asynchronous execution on the specified file
|
||||
* descriptor. The specified handler is enqueued with the data read from the
|
||||
* file descriptor when the operation has completed or an error occurs.
|
||||
*
|
||||
* The data object passed to the handler will be automatically released by the
|
||||
* system when the handler returns. It is the responsibility of the application
|
||||
* to retain, concatenate or copy the data object if it is needed after the
|
||||
* handler returns.
|
||||
*
|
||||
* The data object passed to the handler will only contain as much data as is
|
||||
* currently available from the file descriptor (up to the specified length).
|
||||
*
|
||||
* If an unrecoverable error occurs on the file descriptor, the handler will be
|
||||
* enqueued with the appropriate error code along with a data object of any data
|
||||
* that could be read successfully.
|
||||
*
|
||||
* An invocation of the handler with an error code of zero and an empty data
|
||||
* object indicates that EOF was reached.
|
||||
*
|
||||
* The system takes control of the file descriptor until the handler is
|
||||
* enqueued, and during this time file descriptor flags such as O_NONBLOCK will
|
||||
* be modified by the system on behalf of the application. It is an error for
|
||||
* the application to modify a file descriptor directly while it is under the
|
||||
* control of the system, but it may create additional dispatch I/O convenience
|
||||
* operations or dispatch I/O channels associated with that file descriptor.
|
||||
*
|
||||
* @param fd The file descriptor from which to read the data.
|
||||
* @param length The length of data to read from the file descriptor,
|
||||
* or SIZE_MAX to indicate that all of the data currently
|
||||
* available from the file descriptor should be read.
|
||||
* @param queue The dispatch queue to which the handler should be
|
||||
* submitted.
|
||||
* @param handler The handler to enqueue when data is ready to be
|
||||
* delivered.
|
||||
* param data The data read from the file descriptor.
|
||||
* param error An errno condition for the read operation or
|
||||
* zero if the read was successful.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.7), ios(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL3 DISPATCH_NONNULL4 DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_read(dispatch_fd_t fd,
|
||||
size_t length,
|
||||
dispatch_queue_t queue,
|
||||
void (^handler)(dispatch_data_t data, int error));
|
||||
|
||||
/*!
|
||||
* @function dispatch_write
|
||||
* Schedule a write operation for asynchronous execution on the specified file
|
||||
* descriptor. The specified handler is enqueued when the operation has
|
||||
* completed or an error occurs.
|
||||
*
|
||||
* If an unrecoverable error occurs on the file descriptor, the handler will be
|
||||
* enqueued with the appropriate error code along with the data that could not
|
||||
* be successfully written.
|
||||
*
|
||||
* An invocation of the handler with an error code of zero indicates that the
|
||||
* data was fully written to the channel.
|
||||
*
|
||||
* The system takes control of the file descriptor until the handler is
|
||||
* enqueued, and during this time file descriptor flags such as O_NONBLOCK will
|
||||
* be modified by the system on behalf of the application. It is an error for
|
||||
* the application to modify a file descriptor directly while it is under the
|
||||
* control of the system, but it may create additional dispatch I/O convenience
|
||||
* operations or dispatch I/O channels associated with that file descriptor.
|
||||
*
|
||||
* @param fd The file descriptor to which to write the data.
|
||||
* @param data The data object to write to the file descriptor.
|
||||
* @param queue The dispatch queue to which the handler should be
|
||||
* submitted.
|
||||
* @param handler The handler to enqueue when the data has been written.
|
||||
* param data The data that could not be written to the I/O
|
||||
* channel, or NULL.
|
||||
* param error An errno condition for the write operation or
|
||||
* zero if the write was successful.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.7), ios(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_NONNULL3 DISPATCH_NONNULL4
|
||||
DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_write(dispatch_fd_t fd,
|
||||
dispatch_data_t data,
|
||||
dispatch_queue_t queue,
|
||||
void (^handler)(dispatch_data_t _Nullable data, int error));
|
||||
#endif /* __BLOCKS__ */
|
||||
|
||||
/*!
|
||||
* @functiongroup Dispatch I/O Channel API
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_io_t
|
||||
* A dispatch I/O channel represents the asynchronous I/O policy applied to a
|
||||
* file descriptor. I/O channels are first class dispatch objects and may be
|
||||
* retained and released, suspended and resumed, etc.
|
||||
*/
|
||||
DISPATCH_DECL(dispatch_io);
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_io_type_t
|
||||
* The type of a dispatch I/O channel:
|
||||
*
|
||||
* @const DISPATCH_IO_STREAM A dispatch I/O channel representing a stream of
|
||||
* bytes. Read and write operations on a channel of this type are performed
|
||||
* serially (in order of creation) and read/write data at the file pointer
|
||||
* position that is current at the time the operation starts executing.
|
||||
* Operations of different type (read vs. write) may be performed simultaneously.
|
||||
* Offsets passed to operations on a channel of this type are ignored.
|
||||
*
|
||||
* @const DISPATCH_IO_RANDOM A dispatch I/O channel representing a random
|
||||
* access file. Read and write operations on a channel of this type may be
|
||||
* performed concurrently and read/write data at the specified offset. Offsets
|
||||
* are interpreted relative to the file pointer position current at the time the
|
||||
* I/O channel is created. Attempting to create a channel of this type for a
|
||||
* file descriptor that is not seekable will result in an error.
|
||||
*/
|
||||
#define DISPATCH_IO_STREAM 0
|
||||
#define DISPATCH_IO_RANDOM 1
|
||||
|
||||
typedef unsigned long dispatch_io_type_t;
|
||||
|
||||
#ifdef __BLOCKS__
|
||||
/*!
|
||||
* @function dispatch_io_create
|
||||
* Create a dispatch I/O channel associated with a file descriptor. The system
|
||||
* takes control of the file descriptor until the channel is closed, an error
|
||||
* occurs on the file descriptor or all references to the channel are released.
|
||||
* At that time the specified cleanup handler will be enqueued and control over
|
||||
* the file descriptor relinquished.
|
||||
*
|
||||
* While a file descriptor is under the control of a dispatch I/O channel, file
|
||||
* descriptor flags such as O_NONBLOCK will be modified by the system on behalf
|
||||
* of the application. It is an error for the application to modify a file
|
||||
* descriptor directly while it is under the control of a dispatch I/O channel,
|
||||
* but it may create additional channels associated with that file descriptor.
|
||||
*
|
||||
* @param type The desired type of I/O channel (DISPATCH_IO_STREAM
|
||||
* or DISPATCH_IO_RANDOM).
|
||||
* @param fd The file descriptor to associate with the I/O channel.
|
||||
* @param queue The dispatch queue to which the handler should be submitted.
|
||||
* @param cleanup_handler The handler to enqueue when the system
|
||||
* relinquishes control over the file descriptor.
|
||||
* param error An errno condition if control is relinquished
|
||||
* because channel creation failed, zero otherwise.
|
||||
* @result The newly created dispatch I/O channel or NULL if an error
|
||||
* occurred (invalid type specified).
|
||||
*/
|
||||
API_AVAILABLE(macos(10.7), ios(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
|
||||
DISPATCH_NOTHROW
|
||||
dispatch_io_t
|
||||
dispatch_io_create(dispatch_io_type_t type,
|
||||
dispatch_fd_t fd,
|
||||
dispatch_queue_t queue,
|
||||
void (^cleanup_handler)(int error));
|
||||
|
||||
/*!
|
||||
* @function dispatch_io_create_with_path
|
||||
* Create a dispatch I/O channel associated with a path name. The specified
|
||||
* path, oflag and mode parameters will be passed to open(2) when the first I/O
|
||||
* operation on the channel is ready to execute and the resulting file
|
||||
* descriptor will remain open and under the control of the system until the
|
||||
* channel is closed, an error occurs on the file descriptor or all references
|
||||
* to the channel are released. At that time the file descriptor will be closed
|
||||
* and the specified cleanup handler will be enqueued.
|
||||
*
|
||||
* @param type The desired type of I/O channel (DISPATCH_IO_STREAM
|
||||
* or DISPATCH_IO_RANDOM).
|
||||
* @param path The absolute path to associate with the I/O channel.
|
||||
* @param oflag The flags to pass to open(2) when opening the file at
|
||||
* path.
|
||||
* @param mode The mode to pass to open(2) when creating the file at
|
||||
* path (i.e. with flag O_CREAT), zero otherwise.
|
||||
* @param queue The dispatch queue to which the handler should be
|
||||
* submitted.
|
||||
* @param cleanup_handler The handler to enqueue when the system
|
||||
* has closed the file at path.
|
||||
* param error An errno condition if control is relinquished
|
||||
* because channel creation or opening of the
|
||||
* specified file failed, zero otherwise.
|
||||
* @result The newly created dispatch I/O channel or NULL if an error
|
||||
* occurred (invalid type or non-absolute path specified).
|
||||
*/
|
||||
API_AVAILABLE(macos(10.7), ios(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED
|
||||
DISPATCH_WARN_RESULT DISPATCH_NOTHROW
|
||||
dispatch_io_t
|
||||
dispatch_io_create_with_path(dispatch_io_type_t type,
|
||||
const char *path, int oflag, mode_t mode,
|
||||
dispatch_queue_t queue,
|
||||
void (^cleanup_handler)(int error));
|
||||
|
||||
/*!
|
||||
* @function dispatch_io_create_with_io
|
||||
* Create a new dispatch I/O channel from an existing dispatch I/O channel.
|
||||
* The new channel inherits the file descriptor or path name associated with
|
||||
* the existing channel, but not its channel type or policies.
|
||||
*
|
||||
* If the existing channel is associated with a file descriptor, control by the
|
||||
* system over that file descriptor is extended until the new channel is also
|
||||
* closed, an error occurs on the file descriptor, or all references to both
|
||||
* channels are released. At that time the specified cleanup handler will be
|
||||
* enqueued and control over the file descriptor relinquished.
|
||||
*
|
||||
* While a file descriptor is under the control of a dispatch I/O channel, file
|
||||
* descriptor flags such as O_NONBLOCK will be modified by the system on behalf
|
||||
* of the application. It is an error for the application to modify a file
|
||||
* descriptor directly while it is under the control of a dispatch I/O channel,
|
||||
* but it may create additional channels associated with that file descriptor.
|
||||
*
|
||||
* @param type The desired type of I/O channel (DISPATCH_IO_STREAM
|
||||
* or DISPATCH_IO_RANDOM).
|
||||
* @param io The existing channel to create the new I/O channel from.
|
||||
* @param queue The dispatch queue to which the handler should be submitted.
|
||||
* @param cleanup_handler The handler to enqueue when the system
|
||||
* relinquishes control over the file descriptor
|
||||
* (resp. closes the file at path) associated with
|
||||
* the existing channel.
|
||||
* param error An errno condition if control is relinquished
|
||||
* because channel creation failed, zero otherwise.
|
||||
* @result The newly created dispatch I/O channel or NULL if an error
|
||||
* occurred (invalid type specified).
|
||||
*/
|
||||
API_AVAILABLE(macos(10.7), ios(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED
|
||||
DISPATCH_WARN_RESULT DISPATCH_NOTHROW
|
||||
dispatch_io_t
|
||||
dispatch_io_create_with_io(dispatch_io_type_t type,
|
||||
dispatch_io_t io,
|
||||
dispatch_queue_t queue,
|
||||
void (^cleanup_handler)(int error));
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_io_handler_t
|
||||
* The prototype of I/O handler blocks for dispatch I/O operations.
|
||||
*
|
||||
* @param done A flag indicating whether the operation is complete.
|
||||
* @param data The data object to be handled.
|
||||
* @param error An errno condition for the operation.
|
||||
*/
|
||||
typedef void (^dispatch_io_handler_t)(bool done, dispatch_data_t _Nullable data,
|
||||
int error);
|
||||
|
||||
/*!
|
||||
* @function dispatch_io_read
|
||||
* Schedule a read operation for asynchronous execution on the specified I/O
|
||||
* channel. The I/O handler is enqueued one or more times depending on the
|
||||
* general load of the system and the policy specified on the I/O channel.
|
||||
*
|
||||
* Any data read from the channel is described by the dispatch data object
|
||||
* passed to the I/O handler. This object will be automatically released by the
|
||||
* system when the I/O handler returns. It is the responsibility of the
|
||||
* application to retain, concatenate or copy the data object if it is needed
|
||||
* after the I/O handler returns.
|
||||
*
|
||||
* Dispatch I/O handlers are not reentrant. The system will ensure that no new
|
||||
* I/O handler instance is invoked until the previously enqueued handler block
|
||||
* has returned.
|
||||
*
|
||||
* An invocation of the I/O handler with the done flag set indicates that the
|
||||
* read operation is complete and that the handler will not be enqueued again.
|
||||
*
|
||||
* If an unrecoverable error occurs on the I/O channel's underlying file
|
||||
* descriptor, the I/O handler will be enqueued with the done flag set, the
|
||||
* appropriate error code and a NULL data object.
|
||||
*
|
||||
* An invocation of the I/O handler with the done flag set, an error code of
|
||||
* zero and an empty data object indicates that EOF was reached.
|
||||
*
|
||||
* @param channel The dispatch I/O channel from which to read the data.
|
||||
* @param offset The offset relative to the channel position from which
|
||||
* to start reading (only for DISPATCH_IO_RANDOM).
|
||||
* @param length The length of data to read from the I/O channel, or
|
||||
* SIZE_MAX to indicate that data should be read until EOF
|
||||
* is reached.
|
||||
* @param queue The dispatch queue to which the I/O handler should be
|
||||
* submitted.
|
||||
* @param io_handler The I/O handler to enqueue when data is ready to be
|
||||
* delivered.
|
||||
* param done A flag indicating whether the operation is complete.
|
||||
* param data An object with the data most recently read from the
|
||||
* I/O channel as part of this read operation, or NULL.
|
||||
* param error An errno condition for the read operation or zero if
|
||||
* the read was successful.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.7), ios(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL4 DISPATCH_NONNULL5
|
||||
DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_io_read(dispatch_io_t channel,
|
||||
off_t offset,
|
||||
size_t length,
|
||||
dispatch_queue_t queue,
|
||||
dispatch_io_handler_t io_handler);
|
||||
|
||||
/*!
|
||||
* @function dispatch_io_write
|
||||
* Schedule a write operation for asynchronous execution on the specified I/O
|
||||
* channel. The I/O handler is enqueued one or more times depending on the
|
||||
* general load of the system and the policy specified on the I/O channel.
|
||||
*
|
||||
* Any data remaining to be written to the I/O channel is described by the
|
||||
* dispatch data object passed to the I/O handler. This object will be
|
||||
* automatically released by the system when the I/O handler returns. It is the
|
||||
* responsibility of the application to retain, concatenate or copy the data
|
||||
* object if it is needed after the I/O handler returns.
|
||||
*
|
||||
* Dispatch I/O handlers are not reentrant. The system will ensure that no new
|
||||
* I/O handler instance is invoked until the previously enqueued handler block
|
||||
* has returned.
|
||||
*
|
||||
* An invocation of the I/O handler with the done flag set indicates that the
|
||||
* write operation is complete and that the handler will not be enqueued again.
|
||||
*
|
||||
* If an unrecoverable error occurs on the I/O channel's underlying file
|
||||
* descriptor, the I/O handler will be enqueued with the done flag set, the
|
||||
* appropriate error code and an object containing the data that could not be
|
||||
* written.
|
||||
*
|
||||
* An invocation of the I/O handler with the done flag set and an error code of
|
||||
* zero indicates that the data was fully written to the channel.
|
||||
*
|
||||
* @param channel The dispatch I/O channel on which to write the data.
|
||||
* @param offset The offset relative to the channel position from which
|
||||
* to start writing (only for DISPATCH_IO_RANDOM).
|
||||
* @param data The data to write to the I/O channel. The data object
|
||||
* will be retained by the system until the write operation
|
||||
* is complete.
|
||||
* @param queue The dispatch queue to which the I/O handler should be
|
||||
* submitted.
|
||||
* @param io_handler The I/O handler to enqueue when data has been delivered.
|
||||
* param done A flag indicating whether the operation is complete.
|
||||
* param data An object of the data remaining to be
|
||||
* written to the I/O channel as part of this write
|
||||
* operation, or NULL.
|
||||
* param error An errno condition for the write operation or zero
|
||||
* if the write was successful.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.7), ios(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NONNULL4
|
||||
DISPATCH_NONNULL5 DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_io_write(dispatch_io_t channel,
|
||||
off_t offset,
|
||||
dispatch_data_t data,
|
||||
dispatch_queue_t queue,
|
||||
dispatch_io_handler_t io_handler);
|
||||
#endif /* __BLOCKS__ */
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_io_close_flags_t
|
||||
* The type of flags you can set on a dispatch_io_close() call
|
||||
*
|
||||
* @const DISPATCH_IO_STOP Stop outstanding operations on a channel when
|
||||
* the channel is closed.
|
||||
*/
|
||||
#define DISPATCH_IO_STOP 0x1
|
||||
|
||||
typedef unsigned long dispatch_io_close_flags_t;
|
||||
|
||||
/*!
|
||||
* @function dispatch_io_close
|
||||
* Close the specified I/O channel to new read or write operations; scheduling
|
||||
* operations on a closed channel results in their handler returning an error.
|
||||
*
|
||||
* If the DISPATCH_IO_STOP flag is provided, the system will make a best effort
|
||||
* to interrupt any outstanding read and write operations on the I/O channel,
|
||||
* otherwise those operations will run to completion normally.
|
||||
* Partial results of read and write operations may be returned even after a
|
||||
* channel is closed with the DISPATCH_IO_STOP flag.
|
||||
* The final invocation of an I/O handler of an interrupted operation will be
|
||||
* passed an ECANCELED error code, as will the I/O handler of an operation
|
||||
* scheduled on a closed channel.
|
||||
*
|
||||
* @param channel The dispatch I/O channel to close.
|
||||
* @param flags The flags for the close operation.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.7), ios(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_io_close(dispatch_io_t channel, dispatch_io_close_flags_t flags);
|
||||
|
||||
#ifdef __BLOCKS__
|
||||
/*!
|
||||
* @function dispatch_io_barrier
|
||||
* Schedule a barrier operation on the specified I/O channel; all previously
|
||||
* scheduled operations on the channel will complete before the provided
|
||||
* barrier block is enqueued onto the global queue determined by the channel's
|
||||
* target queue, and no subsequently scheduled operations will start until the
|
||||
* barrier block has returned.
|
||||
*
|
||||
* If multiple channels are associated with the same file descriptor, a barrier
|
||||
* operation scheduled on any of these channels will act as a barrier across all
|
||||
* channels in question, i.e. all previously scheduled operations on any of the
|
||||
* channels will complete before the barrier block is enqueued, and no
|
||||
* operations subsequently scheduled on any of the channels will start until the
|
||||
* barrier block has returned.
|
||||
*
|
||||
* While the barrier block is running, it may safely operate on the channel's
|
||||
* underlying file descriptor with fsync(2), lseek(2) etc. (but not close(2)).
|
||||
*
|
||||
* @param channel The dispatch I/O channel to schedule the barrier on.
|
||||
* @param barrier The barrier block.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.7), ios(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_io_barrier(dispatch_io_t channel, dispatch_block_t barrier);
|
||||
#endif /* __BLOCKS__ */
|
||||
|
||||
/*!
|
||||
* @function dispatch_io_get_descriptor
|
||||
* Returns the file descriptor underlying a dispatch I/O channel.
|
||||
*
|
||||
* Will return -1 for a channel closed with dispatch_io_close() and for a
|
||||
* channel associated with a path name that has not yet been open(2)ed.
|
||||
*
|
||||
* If called from a barrier block scheduled on a channel associated with a path
|
||||
* name that has not yet been open(2)ed, this will trigger the channel open(2)
|
||||
* operation and return the resulting file descriptor.
|
||||
*
|
||||
* @param channel The dispatch I/O channel to query.
|
||||
* @result The file descriptor underlying the channel, or -1.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.7), ios(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_WARN_RESULT DISPATCH_NOTHROW
|
||||
dispatch_fd_t
|
||||
dispatch_io_get_descriptor(dispatch_io_t channel);
|
||||
|
||||
/*!
|
||||
* @function dispatch_io_set_high_water
|
||||
* Set a high water mark on the I/O channel for all operations.
|
||||
*
|
||||
* The system will make a best effort to enqueue I/O handlers with partial
|
||||
* results as soon the number of bytes processed by an operation (i.e. read or
|
||||
* written) reaches the high water mark.
|
||||
*
|
||||
* The size of data objects passed to I/O handlers for this channel will never
|
||||
* exceed the specified high water mark.
|
||||
*
|
||||
* The default value for the high water mark is unlimited (i.e. SIZE_MAX).
|
||||
*
|
||||
* @param channel The dispatch I/O channel on which to set the policy.
|
||||
* @param high_water The number of bytes to use as a high water mark.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.7), ios(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_io_set_high_water(dispatch_io_t channel, size_t high_water);
|
||||
|
||||
/*!
|
||||
* @function dispatch_io_set_low_water
|
||||
* Set a low water mark on the I/O channel for all operations.
|
||||
*
|
||||
* The system will process (i.e. read or write) at least the low water mark
|
||||
* number of bytes for an operation before enqueueing I/O handlers with partial
|
||||
* results.
|
||||
*
|
||||
* The size of data objects passed to intermediate I/O handler invocations for
|
||||
* this channel (i.e. excluding the final invocation) will never be smaller than
|
||||
* the specified low water mark, except if the channel has an interval with the
|
||||
* DISPATCH_IO_STRICT_INTERVAL flag set or if EOF or an error was encountered.
|
||||
*
|
||||
* I/O handlers should be prepared to receive amounts of data significantly
|
||||
* larger than the low water mark in general. If an I/O handler requires
|
||||
* intermediate results of fixed size, set both the low and and the high water
|
||||
* mark to that size.
|
||||
*
|
||||
* The default value for the low water mark is unspecified, but must be assumed
|
||||
* to be such that intermediate handler invocations may occur.
|
||||
* If I/O handler invocations with partial results are not desired, set the
|
||||
* low water mark to SIZE_MAX.
|
||||
*
|
||||
* @param channel The dispatch I/O channel on which to set the policy.
|
||||
* @param low_water The number of bytes to use as a low water mark.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.7), ios(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_io_set_low_water(dispatch_io_t channel, size_t low_water);
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_io_interval_flags_t
|
||||
* Type of flags to set on dispatch_io_set_interval()
|
||||
*
|
||||
* @const DISPATCH_IO_STRICT_INTERVAL Enqueue I/O handlers at a channel's
|
||||
* interval setting even if the amount of data ready to be delivered is inferior
|
||||
* to the low water mark (or zero).
|
||||
*/
|
||||
#define DISPATCH_IO_STRICT_INTERVAL 0x1
|
||||
|
||||
typedef unsigned long dispatch_io_interval_flags_t;
|
||||
|
||||
/*!
|
||||
* @function dispatch_io_set_interval
|
||||
* Set a nanosecond interval at which I/O handlers are to be enqueued on the
|
||||
* I/O channel for all operations.
|
||||
*
|
||||
* This allows an application to receive periodic feedback on the progress of
|
||||
* read and write operations, e.g. for the purposes of displaying progress bars.
|
||||
*
|
||||
* If the amount of data ready to be delivered to an I/O handler at the interval
|
||||
* is inferior to the channel low water mark, the handler will only be enqueued
|
||||
* if the DISPATCH_IO_STRICT_INTERVAL flag is set.
|
||||
*
|
||||
* Note that the system may defer enqueueing interval I/O handlers by a small
|
||||
* unspecified amount of leeway in order to align with other system activity for
|
||||
* improved system performance or power consumption.
|
||||
*
|
||||
* @param channel The dispatch I/O channel on which to set the policy.
|
||||
* @param interval The interval in nanoseconds at which delivery of the I/O
|
||||
* handler is desired.
|
||||
* @param flags Flags indicating desired data delivery behavior at
|
||||
* interval time.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.7), ios(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_io_set_interval(dispatch_io_t channel,
|
||||
uint64_t interval,
|
||||
dispatch_io_interval_flags_t flags);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_END
|
||||
|
||||
#endif /* __DISPATCH_IO__ */
|
||||
550
Telegram/ThirdParty/dispatch/dispatch/object.h
vendored
Normal file
550
Telegram/ThirdParty/dispatch/dispatch/object.h
vendored
Normal file
@@ -0,0 +1,550 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2012 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#ifndef __DISPATCH_OBJECT__
|
||||
#define __DISPATCH_OBJECT__
|
||||
|
||||
#ifndef __DISPATCH_INDIRECT__
|
||||
#error "Please #include <dispatch/dispatch.h> instead of this file directly."
|
||||
#include <dispatch/base.h> // for HeaderDoc
|
||||
#endif
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_object_t
|
||||
*
|
||||
* @abstract
|
||||
* Abstract base type for all dispatch objects.
|
||||
* The details of the type definition are language-specific.
|
||||
*
|
||||
* @discussion
|
||||
* Dispatch objects are reference counted via calls to dispatch_retain() and
|
||||
* dispatch_release().
|
||||
*/
|
||||
|
||||
#if OS_OBJECT_USE_OBJC
|
||||
/*
|
||||
* By default, dispatch objects are declared as Objective-C types when building
|
||||
* with an Objective-C compiler. This allows them to participate in ARC, in RR
|
||||
* management by the Blocks runtime and in leaks checking by the static
|
||||
* analyzer, and enables them to be added to Cocoa collections.
|
||||
* See <os/object.h> for details.
|
||||
*/
|
||||
OS_OBJECT_DECL_CLASS(dispatch_object);
|
||||
|
||||
#if OS_OBJECT_SWIFT3
|
||||
#define DISPATCH_DECL(name) OS_OBJECT_DECL_SUBCLASS_SWIFT(name, dispatch_object)
|
||||
#define DISPATCH_DECL_SUBCLASS(name, base) OS_OBJECT_DECL_SUBCLASS_SWIFT(name, base)
|
||||
#else // OS_OBJECT_SWIFT3
|
||||
#define DISPATCH_DECL(name) OS_OBJECT_DECL_SUBCLASS(name, dispatch_object)
|
||||
#define DISPATCH_DECL_SUBCLASS(name, base) OS_OBJECT_DECL_SUBCLASS(name, base)
|
||||
|
||||
DISPATCH_INLINE DISPATCH_ALWAYS_INLINE DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
void
|
||||
_dispatch_object_validate(dispatch_object_t object)
|
||||
{
|
||||
void *isa = *(void *volatile*)(OS_OBJECT_BRIDGE void*)object;
|
||||
(void)isa;
|
||||
}
|
||||
#endif // OS_OBJECT_SWIFT3
|
||||
|
||||
#define DISPATCH_GLOBAL_OBJECT(type, object) ((OS_OBJECT_BRIDGE type)&(object))
|
||||
#define DISPATCH_RETURNS_RETAINED OS_OBJECT_RETURNS_RETAINED
|
||||
#elif defined(__cplusplus) && !defined(__DISPATCH_BUILDING_DISPATCH__)
|
||||
/*
|
||||
* Dispatch objects are NOT C++ objects. Nevertheless, we can at least keep C++
|
||||
* aware of type compatibility.
|
||||
*/
|
||||
typedef struct dispatch_object_s {
|
||||
private:
|
||||
dispatch_object_s();
|
||||
~dispatch_object_s();
|
||||
dispatch_object_s(const dispatch_object_s &);
|
||||
void operator=(const dispatch_object_s &);
|
||||
} *dispatch_object_t;
|
||||
#define DISPATCH_DECL(name) \
|
||||
typedef struct name##_s : public dispatch_object_s {} *name##_t
|
||||
#define DISPATCH_DECL_SUBCLASS(name, base) \
|
||||
typedef struct name##_s : public base##_s {} *name##_t
|
||||
#define DISPATCH_GLOBAL_OBJECT(type, object) (static_cast<type>(&(object)))
|
||||
#define DISPATCH_RETURNS_RETAINED
|
||||
#else /* Plain C */
|
||||
#ifndef __DISPATCH_BUILDING_DISPATCH__
|
||||
typedef union {
|
||||
struct _os_object_s *_os_obj;
|
||||
struct dispatch_object_s *_do;
|
||||
struct dispatch_queue_s *_dq;
|
||||
struct dispatch_queue_attr_s *_dqa;
|
||||
struct dispatch_group_s *_dg;
|
||||
struct dispatch_source_s *_ds;
|
||||
struct dispatch_mach_s *_dm;
|
||||
struct dispatch_mach_msg_s *_dmsg;
|
||||
struct dispatch_semaphore_s *_dsema;
|
||||
struct dispatch_data_s *_ddata;
|
||||
struct dispatch_io_s *_dchannel;
|
||||
} dispatch_object_t DISPATCH_TRANSPARENT_UNION;
|
||||
#endif // !__DISPATCH_BUILDING_DISPATCH__
|
||||
#define DISPATCH_DECL(name) typedef struct name##_s *name##_t
|
||||
#define DISPATCH_DECL_SUBCLASS(name, base) typedef base##_t name##_t
|
||||
#define DISPATCH_GLOBAL_OBJECT(type, object) ((type)&(object))
|
||||
#define DISPATCH_RETURNS_RETAINED
|
||||
#endif
|
||||
|
||||
#if OS_OBJECT_SWIFT3 && OS_OBJECT_USE_OBJC
|
||||
#define DISPATCH_SOURCE_TYPE_DECL(name) \
|
||||
DISPATCH_EXPORT struct dispatch_source_type_s \
|
||||
_dispatch_source_type_##name; \
|
||||
OS_OBJECT_DECL_PROTOCOL(dispatch_source_##name, <OS_dispatch_source>); \
|
||||
OS_OBJECT_CLASS_IMPLEMENTS_PROTOCOL( \
|
||||
dispatch_source, dispatch_source_##name)
|
||||
#define DISPATCH_SOURCE_DECL(name) \
|
||||
DISPATCH_DECL(name); \
|
||||
OS_OBJECT_DECL_PROTOCOL(name, <NSObject>); \
|
||||
OS_OBJECT_CLASS_IMPLEMENTS_PROTOCOL(name, name)
|
||||
#ifndef DISPATCH_DATA_DECL
|
||||
#define DISPATCH_DATA_DECL(name) OS_OBJECT_DECL_SWIFT(name)
|
||||
#endif // DISPATCH_DATA_DECL
|
||||
#else
|
||||
#define DISPATCH_SOURCE_DECL(name) \
|
||||
DISPATCH_DECL(name);
|
||||
#define DISPATCH_DATA_DECL(name) DISPATCH_DECL(name)
|
||||
#define DISPATCH_SOURCE_TYPE_DECL(name) \
|
||||
DISPATCH_EXPORT const struct dispatch_source_type_s \
|
||||
_dispatch_source_type_##name
|
||||
#endif
|
||||
|
||||
#ifdef __BLOCKS__
|
||||
/*!
|
||||
* @typedef dispatch_block_t
|
||||
*
|
||||
* @abstract
|
||||
* The type of blocks submitted to dispatch queues, which take no arguments
|
||||
* and have no return value.
|
||||
*
|
||||
* @discussion
|
||||
* When not building with Objective-C ARC, a block object allocated on or
|
||||
* copied to the heap must be released with a -[release] message or the
|
||||
* Block_release() function.
|
||||
*
|
||||
* The declaration of a block literal allocates storage on the stack.
|
||||
* Therefore, this is an invalid construct:
|
||||
* <code>
|
||||
* dispatch_block_t block;
|
||||
* if (x) {
|
||||
* block = ^{ printf("true\n"); };
|
||||
* } else {
|
||||
* block = ^{ printf("false\n"); };
|
||||
* }
|
||||
* block(); // unsafe!!!
|
||||
* </code>
|
||||
*
|
||||
* What is happening behind the scenes:
|
||||
* <code>
|
||||
* if (x) {
|
||||
* struct Block __tmp_1 = ...; // setup details
|
||||
* block = &__tmp_1;
|
||||
* } else {
|
||||
* struct Block __tmp_2 = ...; // setup details
|
||||
* block = &__tmp_2;
|
||||
* }
|
||||
* </code>
|
||||
*
|
||||
* As the example demonstrates, the address of a stack variable is escaping the
|
||||
* scope in which it is allocated. That is a classic C bug.
|
||||
*
|
||||
* Instead, the block literal must be copied to the heap with the Block_copy()
|
||||
* function or by sending it a -[copy] message.
|
||||
*/
|
||||
typedef void (^dispatch_block_t)(void);
|
||||
#endif // __BLOCKS__
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/*!
|
||||
* @function dispatch_retain
|
||||
*
|
||||
* @abstract
|
||||
* Increment the reference count of a dispatch object.
|
||||
*
|
||||
* @discussion
|
||||
* Calls to dispatch_retain() must be balanced with calls to
|
||||
* dispatch_release().
|
||||
*
|
||||
* @param object
|
||||
* The object to retain.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
DISPATCH_SWIFT_UNAVAILABLE("Can't be used with ARC")
|
||||
void
|
||||
dispatch_retain(dispatch_object_t object);
|
||||
#if OS_OBJECT_USE_OBJC_RETAIN_RELEASE
|
||||
#undef dispatch_retain
|
||||
#define dispatch_retain(object) \
|
||||
__extension__({ dispatch_object_t _o = (object); \
|
||||
_dispatch_object_validate(_o); (void)[_o retain]; })
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @function dispatch_release
|
||||
*
|
||||
* @abstract
|
||||
* Decrement the reference count of a dispatch object.
|
||||
*
|
||||
* @discussion
|
||||
* A dispatch object is asynchronously deallocated once all references are
|
||||
* released (i.e. the reference count becomes zero). The system does not
|
||||
* guarantee that a given client is the last or only reference to a given
|
||||
* object.
|
||||
*
|
||||
* @param object
|
||||
* The object to release.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
DISPATCH_SWIFT_UNAVAILABLE("Can't be used with ARC")
|
||||
void
|
||||
dispatch_release(dispatch_object_t object);
|
||||
#if OS_OBJECT_USE_OBJC_RETAIN_RELEASE
|
||||
#undef dispatch_release
|
||||
#define dispatch_release(object) \
|
||||
__extension__({ dispatch_object_t _o = (object); \
|
||||
_dispatch_object_validate(_o); [_o release]; })
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @function dispatch_get_context
|
||||
*
|
||||
* @abstract
|
||||
* Returns the application defined context of the object.
|
||||
*
|
||||
* @param object
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @result
|
||||
* The context of the object; may be NULL.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_PURE DISPATCH_WARN_RESULT
|
||||
DISPATCH_NOTHROW
|
||||
void *_Nullable
|
||||
dispatch_get_context(dispatch_object_t object);
|
||||
|
||||
/*!
|
||||
* @function dispatch_set_context
|
||||
*
|
||||
* @abstract
|
||||
* Associates an application defined context with the object.
|
||||
*
|
||||
* @param object
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @param context
|
||||
* The new client defined context for the object. This may be NULL.
|
||||
*
|
||||
*/
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_set_context(dispatch_object_t object, void *_Nullable context);
|
||||
|
||||
/*!
|
||||
* @function dispatch_set_finalizer_f
|
||||
*
|
||||
* @abstract
|
||||
* Set the finalizer function for a dispatch object.
|
||||
*
|
||||
* @param object
|
||||
* The dispatch object to modify.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @param finalizer
|
||||
* The finalizer function pointer.
|
||||
*
|
||||
* @discussion
|
||||
* A dispatch object's finalizer will be invoked on the object's target queue
|
||||
* after all references to the object have been released. This finalizer may be
|
||||
* used by the application to release any resources associated with the object,
|
||||
* such as freeing the object's context.
|
||||
* The context parameter passed to the finalizer function is the current
|
||||
* context of the dispatch object at the time the finalizer call is made.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_set_finalizer_f(dispatch_object_t object,
|
||||
dispatch_function_t _Nullable finalizer);
|
||||
|
||||
/*!
|
||||
* @function dispatch_activate
|
||||
*
|
||||
* @abstract
|
||||
* Activates the specified dispatch object.
|
||||
*
|
||||
* @discussion
|
||||
* Dispatch objects such as queues and sources may be created in an inactive
|
||||
* state. Objects in this state have to be activated before any blocks
|
||||
* associated with them will be invoked.
|
||||
*
|
||||
* The target queue of inactive objects can be changed using
|
||||
* dispatch_set_target_queue(). Change of target queue is no longer permitted
|
||||
* once an initially inactive object has been activated.
|
||||
*
|
||||
* Calling dispatch_activate() on an active object has no effect.
|
||||
* Releasing the last reference count on an inactive object is undefined.
|
||||
*
|
||||
* @param object
|
||||
* The object to be activated.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_activate(dispatch_object_t object);
|
||||
|
||||
/*!
|
||||
* @function dispatch_suspend
|
||||
*
|
||||
* @abstract
|
||||
* Suspends the invocation of blocks on a dispatch object.
|
||||
*
|
||||
* @discussion
|
||||
* A suspended object will not invoke any blocks associated with it. The
|
||||
* suspension of an object will occur after any running block associated with
|
||||
* the object completes.
|
||||
*
|
||||
* Calls to dispatch_suspend() must be balanced with calls
|
||||
* to dispatch_resume().
|
||||
*
|
||||
* @param object
|
||||
* The object to be suspended.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_suspend(dispatch_object_t object);
|
||||
|
||||
/*!
|
||||
* @function dispatch_resume
|
||||
*
|
||||
* @abstract
|
||||
* Resumes the invocation of blocks on a dispatch object.
|
||||
*
|
||||
* @discussion
|
||||
* Dispatch objects can be suspended with dispatch_suspend(), which increments
|
||||
* an internal suspension count. dispatch_resume() is the inverse operation,
|
||||
* and consumes suspension counts. When the last suspension count is consumed,
|
||||
* blocks associated with the object will be invoked again.
|
||||
*
|
||||
* For backward compatibility reasons, dispatch_resume() on an inactive and not
|
||||
* otherwise suspended dispatch source object has the same effect as calling
|
||||
* dispatch_activate(). For new code, using dispatch_activate() is preferred.
|
||||
*
|
||||
* If the specified object has zero suspension count and is not an inactive
|
||||
* source, this function will result in an assertion and the process being
|
||||
* terminated.
|
||||
*
|
||||
* @param object
|
||||
* The object to be resumed.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_resume(dispatch_object_t object);
|
||||
|
||||
#ifdef __BLOCKS__
|
||||
/*!
|
||||
* @function dispatch_wait
|
||||
*
|
||||
* @abstract
|
||||
* Wait synchronously for an object or until the specified timeout has elapsed.
|
||||
*
|
||||
* @discussion
|
||||
* Type-generic macro that maps to dispatch_block_wait, dispatch_group_wait or
|
||||
* dispatch_semaphore_wait, depending on the type of the first argument.
|
||||
* See documentation for these functions for more details.
|
||||
* This function is unavailable for any other object type.
|
||||
*
|
||||
* @param object
|
||||
* The object to wait on.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @param timeout
|
||||
* When to timeout (see dispatch_time). As a convenience, there are the
|
||||
* DISPATCH_TIME_NOW and DISPATCH_TIME_FOREVER constants.
|
||||
*
|
||||
* @result
|
||||
* Returns zero on success or non-zero on error (i.e. timed out).
|
||||
*/
|
||||
DISPATCH_UNAVAILABLE
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
|
||||
intptr_t
|
||||
dispatch_wait(void *object, dispatch_time_t timeout);
|
||||
#if __has_extension(c_generic_selections)
|
||||
#define dispatch_wait(object, timeout) \
|
||||
_Generic((object), \
|
||||
dispatch_block_t:dispatch_block_wait, \
|
||||
dispatch_group_t:dispatch_group_wait, \
|
||||
dispatch_semaphore_t:dispatch_semaphore_wait \
|
||||
)((object),(timeout))
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @function dispatch_notify
|
||||
*
|
||||
* @abstract
|
||||
* Schedule a notification block to be submitted to a queue when the execution
|
||||
* of a specified object has completed.
|
||||
*
|
||||
* @discussion
|
||||
* Type-generic macro that maps to dispatch_block_notify or
|
||||
* dispatch_group_notify, depending on the type of the first argument.
|
||||
* See documentation for these functions for more details.
|
||||
* This function is unavailable for any other object type.
|
||||
*
|
||||
* @param object
|
||||
* The object to observe.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @param queue
|
||||
* The queue to which the supplied notification block will be submitted when
|
||||
* the observed object completes.
|
||||
*
|
||||
* @param notification_block
|
||||
* The block to submit when the observed object completes.
|
||||
*/
|
||||
DISPATCH_UNAVAILABLE
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_notify(void *object, dispatch_object_t queue,
|
||||
dispatch_block_t notification_block);
|
||||
#if __has_extension(c_generic_selections)
|
||||
#define dispatch_notify(object, queue, notification_block) \
|
||||
_Generic((object), \
|
||||
dispatch_block_t:dispatch_block_notify, \
|
||||
dispatch_group_t:dispatch_group_notify \
|
||||
)((object),(queue), (notification_block))
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @function dispatch_cancel
|
||||
*
|
||||
* @abstract
|
||||
* Cancel the specified object.
|
||||
*
|
||||
* @discussion
|
||||
* Type-generic macro that maps to dispatch_block_cancel or
|
||||
* dispatch_source_cancel, depending on the type of the first argument.
|
||||
* See documentation for these functions for more details.
|
||||
* This function is unavailable for any other object type.
|
||||
*
|
||||
* @param object
|
||||
* The object to cancel.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*/
|
||||
DISPATCH_UNAVAILABLE
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_cancel(void *object);
|
||||
#if __has_extension(c_generic_selections)
|
||||
#define dispatch_cancel(object) \
|
||||
_Generic((object), \
|
||||
dispatch_block_t:dispatch_block_cancel, \
|
||||
dispatch_source_t:dispatch_source_cancel \
|
||||
)((object))
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @function dispatch_testcancel
|
||||
*
|
||||
* @abstract
|
||||
* Test whether the specified object has been canceled
|
||||
*
|
||||
* @discussion
|
||||
* Type-generic macro that maps to dispatch_block_testcancel or
|
||||
* dispatch_source_testcancel, depending on the type of the first argument.
|
||||
* See documentation for these functions for more details.
|
||||
* This function is unavailable for any other object type.
|
||||
*
|
||||
* @param object
|
||||
* The object to test.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @result
|
||||
* Non-zero if canceled and zero if not canceled.
|
||||
*/
|
||||
DISPATCH_UNAVAILABLE
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_WARN_RESULT DISPATCH_PURE
|
||||
DISPATCH_NOTHROW
|
||||
intptr_t
|
||||
dispatch_testcancel(void *object);
|
||||
#if __has_extension(c_generic_selections)
|
||||
#define dispatch_testcancel(object) \
|
||||
_Generic((object), \
|
||||
dispatch_block_t:dispatch_block_testcancel, \
|
||||
dispatch_source_t:dispatch_source_testcancel \
|
||||
)((object))
|
||||
#endif
|
||||
#endif // __BLOCKS__
|
||||
|
||||
/*!
|
||||
* @function dispatch_debug
|
||||
*
|
||||
* @abstract
|
||||
* Programmatically log debug information about a dispatch object.
|
||||
*
|
||||
* @discussion
|
||||
* Programmatically log debug information about a dispatch object. By default,
|
||||
* the log output is sent to syslog at notice level. In the debug version of
|
||||
* the library, the log output is sent to a file in /var/tmp.
|
||||
* The log output destination can be configured via the LIBDISPATCH_LOG
|
||||
* environment variable, valid values are: YES, NO, syslog, stderr, file.
|
||||
*
|
||||
* This function is deprecated and will be removed in a future release.
|
||||
* Objective-C callers may use -debugDescription instead.
|
||||
*
|
||||
* @param object
|
||||
* The object to introspect.
|
||||
*
|
||||
* @param message
|
||||
* The message to log above and beyond the introspection.
|
||||
*/
|
||||
API_DEPRECATED("unsupported interface", macos(10.6,10.9), ios(4.0,6.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_NOTHROW DISPATCH_COLD
|
||||
__attribute__((__format__(printf,2,3)))
|
||||
void
|
||||
dispatch_debug(dispatch_object_t object, const char *message, ...);
|
||||
|
||||
API_DEPRECATED("unsupported interface", macos(10.6,10.9), ios(4.0,6.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_NOTHROW DISPATCH_COLD
|
||||
__attribute__((__format__(printf,2,0)))
|
||||
void
|
||||
dispatch_debugv(dispatch_object_t object, const char *message, va_list ap);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_END
|
||||
|
||||
#endif /* __DISPATCH_OBJECT__ */
|
||||
125
Telegram/ThirdParty/dispatch/dispatch/once.h
vendored
Normal file
125
Telegram/ThirdParty/dispatch/dispatch/once.h
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2010 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#ifndef __DISPATCH_ONCE__
|
||||
#define __DISPATCH_ONCE__
|
||||
|
||||
#ifndef __DISPATCH_INDIRECT__
|
||||
#error "Please #include <dispatch/dispatch.h> instead of this file directly."
|
||||
#include <dispatch/base.h> // for HeaderDoc
|
||||
#endif
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_BEGIN
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_once_t
|
||||
*
|
||||
* @abstract
|
||||
* A predicate for use with dispatch_once(). It must be initialized to zero.
|
||||
* Note: static and global variables default to zero.
|
||||
*/
|
||||
DISPATCH_SWIFT3_UNAVAILABLE("Use lazily initialized globals instead")
|
||||
typedef intptr_t dispatch_once_t;
|
||||
|
||||
#if defined(__x86_64__) || defined(__i386__) || defined(__s390x__)
|
||||
#define DISPATCH_ONCE_INLINE_FASTPATH 1
|
||||
#elif defined(__APPLE__)
|
||||
#define DISPATCH_ONCE_INLINE_FASTPATH 1
|
||||
#else
|
||||
#define DISPATCH_ONCE_INLINE_FASTPATH 0
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @function dispatch_once
|
||||
*
|
||||
* @abstract
|
||||
* Execute a block once and only once.
|
||||
*
|
||||
* @param predicate
|
||||
* A pointer to a dispatch_once_t that is used to test whether the block has
|
||||
* completed or not.
|
||||
*
|
||||
* @param block
|
||||
* The block to execute once.
|
||||
*
|
||||
* @discussion
|
||||
* Always call dispatch_once() before using or testing any variables that are
|
||||
* initialized by the block.
|
||||
*/
|
||||
#ifdef __BLOCKS__
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
DISPATCH_SWIFT3_UNAVAILABLE("Use lazily initialized globals instead")
|
||||
void
|
||||
dispatch_once(dispatch_once_t *predicate,
|
||||
DISPATCH_NOESCAPE dispatch_block_t block);
|
||||
|
||||
#if DISPATCH_ONCE_INLINE_FASTPATH
|
||||
DISPATCH_INLINE DISPATCH_ALWAYS_INLINE DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
DISPATCH_SWIFT3_UNAVAILABLE("Use lazily initialized globals instead")
|
||||
void
|
||||
_dispatch_once(dispatch_once_t *predicate,
|
||||
DISPATCH_NOESCAPE dispatch_block_t block)
|
||||
{
|
||||
if (DISPATCH_EXPECT(*predicate, ~0l) != ~0l) {
|
||||
dispatch_once(predicate, block);
|
||||
} else {
|
||||
dispatch_compiler_barrier();
|
||||
}
|
||||
DISPATCH_COMPILER_CAN_ASSUME(*predicate == ~0l);
|
||||
}
|
||||
#undef dispatch_once
|
||||
#define dispatch_once _dispatch_once
|
||||
#endif
|
||||
#endif // DISPATCH_ONCE_INLINE_FASTPATH
|
||||
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW
|
||||
DISPATCH_SWIFT3_UNAVAILABLE("Use lazily initialized globals instead")
|
||||
void
|
||||
dispatch_once_f(dispatch_once_t *predicate, void *_Nullable context,
|
||||
dispatch_function_t function);
|
||||
|
||||
#if DISPATCH_ONCE_INLINE_FASTPATH
|
||||
DISPATCH_INLINE DISPATCH_ALWAYS_INLINE DISPATCH_NONNULL1 DISPATCH_NONNULL3
|
||||
DISPATCH_NOTHROW
|
||||
DISPATCH_SWIFT3_UNAVAILABLE("Use lazily initialized globals instead")
|
||||
void
|
||||
_dispatch_once_f(dispatch_once_t *predicate, void *_Nullable context,
|
||||
dispatch_function_t function)
|
||||
{
|
||||
if (DISPATCH_EXPECT(*predicate, ~0l) != ~0l) {
|
||||
dispatch_once_f(predicate, context, function);
|
||||
} else {
|
||||
dispatch_compiler_barrier();
|
||||
}
|
||||
DISPATCH_COMPILER_CAN_ASSUME(*predicate == ~0l);
|
||||
}
|
||||
#undef dispatch_once_f
|
||||
#define dispatch_once_f _dispatch_once_f
|
||||
#endif // DISPATCH_ONCE_INLINE_FASTPATH
|
||||
|
||||
__END_DECLS
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_END
|
||||
|
||||
#endif /* __DISPATCH_ONCE__ */
|
||||
1545
Telegram/ThirdParty/dispatch/dispatch/queue.h
vendored
Normal file
1545
Telegram/ThirdParty/dispatch/dispatch/queue.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
117
Telegram/ThirdParty/dispatch/dispatch/semaphore.h
vendored
Normal file
117
Telegram/ThirdParty/dispatch/dispatch/semaphore.h
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2013 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#ifndef __DISPATCH_SEMAPHORE__
|
||||
#define __DISPATCH_SEMAPHORE__
|
||||
|
||||
#ifndef __DISPATCH_INDIRECT__
|
||||
#error "Please #include <dispatch/dispatch.h> instead of this file directly."
|
||||
#include <dispatch/base.h> // for HeaderDoc
|
||||
#endif
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_semaphore_t
|
||||
*
|
||||
* @abstract
|
||||
* A counting semaphore.
|
||||
*/
|
||||
DISPATCH_DECL(dispatch_semaphore);
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/*!
|
||||
* @function dispatch_semaphore_create
|
||||
*
|
||||
* @abstract
|
||||
* Creates new counting semaphore with an initial value.
|
||||
*
|
||||
* @discussion
|
||||
* Passing zero for the value is useful for when two threads need to reconcile
|
||||
* the completion of a particular event. Passing a value greater than zero is
|
||||
* useful for managing a finite pool of resources, where the pool size is equal
|
||||
* to the value.
|
||||
*
|
||||
* @param value
|
||||
* The starting value for the semaphore. Passing a value less than zero will
|
||||
* cause NULL to be returned.
|
||||
*
|
||||
* @result
|
||||
* The newly created semaphore, or NULL on failure.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
|
||||
DISPATCH_NOTHROW
|
||||
dispatch_semaphore_t
|
||||
dispatch_semaphore_create(intptr_t value);
|
||||
|
||||
/*!
|
||||
* @function dispatch_semaphore_wait
|
||||
*
|
||||
* @abstract
|
||||
* Wait (decrement) for a semaphore.
|
||||
*
|
||||
* @discussion
|
||||
* Decrement the counting semaphore. If the resulting value is less than zero,
|
||||
* this function waits for a signal to occur before returning.
|
||||
*
|
||||
* @param dsema
|
||||
* The semaphore. The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @param timeout
|
||||
* When to timeout (see dispatch_time). As a convenience, there are the
|
||||
* DISPATCH_TIME_NOW and DISPATCH_TIME_FOREVER constants.
|
||||
*
|
||||
* @result
|
||||
* Returns zero on success, or non-zero if the timeout occurred.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
intptr_t
|
||||
dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);
|
||||
|
||||
/*!
|
||||
* @function dispatch_semaphore_signal
|
||||
*
|
||||
* @abstract
|
||||
* Signal (increment) a semaphore.
|
||||
*
|
||||
* @discussion
|
||||
* Increment the counting semaphore. If the previous value was less than zero,
|
||||
* this function wakes a waiting thread before returning.
|
||||
*
|
||||
* @param dsema The counting semaphore.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @result
|
||||
* This function returns non-zero if a thread is woken. Otherwise, zero is
|
||||
* returned.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
intptr_t
|
||||
dispatch_semaphore_signal(dispatch_semaphore_t dsema);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_END
|
||||
|
||||
#endif /* __DISPATCH_SEMAPHORE__ */
|
||||
773
Telegram/ThirdParty/dispatch/dispatch/source.h
vendored
Normal file
773
Telegram/ThirdParty/dispatch/dispatch/source.h
vendored
Normal file
@@ -0,0 +1,773 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2013 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#ifndef __DISPATCH_SOURCE__
|
||||
#define __DISPATCH_SOURCE__
|
||||
|
||||
#ifndef __DISPATCH_INDIRECT__
|
||||
#error "Please #include <dispatch/dispatch.h> instead of this file directly."
|
||||
#include <dispatch/base.h> // for HeaderDoc
|
||||
#endif
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
#include <mach/port.h>
|
||||
#include <mach/message.h>
|
||||
#endif
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/*!
|
||||
* @header
|
||||
* The dispatch framework provides a suite of interfaces for monitoring low-
|
||||
* level system objects (file descriptors, Mach ports, signals, VFS nodes, etc.)
|
||||
* for activity and automatically submitting event handler blocks to dispatch
|
||||
* queues when such activity occurs.
|
||||
*
|
||||
* This suite of interfaces is known as the Dispatch Source API.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_source_t
|
||||
*
|
||||
* @abstract
|
||||
* Dispatch sources are used to automatically submit event handler blocks to
|
||||
* dispatch queues in response to external events.
|
||||
*/
|
||||
DISPATCH_SOURCE_DECL(dispatch_source)
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_source_type_t
|
||||
*
|
||||
* @abstract
|
||||
* Constants of this type represent the class of low-level system object that
|
||||
* is being monitored by the dispatch source. Constants of this type are
|
||||
* passed as a parameter to dispatch_source_create() and determine how the
|
||||
* handle argument is interpreted (i.e. as a file descriptor, mach port,
|
||||
* signal number, process identifier, etc.), and how the mask argument is
|
||||
* interpreted.
|
||||
*/
|
||||
typedef const struct dispatch_source_type_s *dispatch_source_type_t;
|
||||
|
||||
/*!
|
||||
* @const DISPATCH_SOURCE_TYPE_DATA_ADD
|
||||
* @discussion A dispatch source that coalesces data obtained via calls to
|
||||
* dispatch_source_merge_data(). An ADD is used to coalesce the data.
|
||||
* The handle is unused (pass zero for now).
|
||||
* The mask is unused (pass zero for now).
|
||||
*/
|
||||
#define DISPATCH_SOURCE_TYPE_DATA_ADD (&_dispatch_source_type_data_add)
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_SOURCE_TYPE_DECL(data_add);
|
||||
|
||||
/*!
|
||||
* @const DISPATCH_SOURCE_TYPE_DATA_OR
|
||||
* @discussion A dispatch source that coalesces data obtained via calls to
|
||||
* dispatch_source_merge_data(). A bitwise OR is used to coalesce the data.
|
||||
* The handle is unused (pass zero for now).
|
||||
* The mask is unused (pass zero for now).
|
||||
*/
|
||||
#define DISPATCH_SOURCE_TYPE_DATA_OR (&_dispatch_source_type_data_or)
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_SOURCE_TYPE_DECL(data_or);
|
||||
|
||||
/*!
|
||||
* @const DISPATCH_SOURCE_TYPE_DATA_REPLACE
|
||||
* @discussion A dispatch source that tracks data obtained via calls to
|
||||
* dispatch_source_merge_data(). Newly obtained data values replace existing
|
||||
* data values not yet delivered to the source handler
|
||||
*
|
||||
* A data value of zero will cause the source handler to not be invoked.
|
||||
*
|
||||
* The handle is unused (pass zero for now).
|
||||
* The mask is unused (pass zero for now).
|
||||
*/
|
||||
#define DISPATCH_SOURCE_TYPE_DATA_REPLACE (&_dispatch_source_type_data_replace)
|
||||
API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0))
|
||||
DISPATCH_SOURCE_TYPE_DECL(data_replace);
|
||||
|
||||
/*!
|
||||
* @const DISPATCH_SOURCE_TYPE_MACH_SEND
|
||||
* @discussion A dispatch source that monitors a Mach port for dead name
|
||||
* notifications (send right no longer has any corresponding receive right).
|
||||
* The handle is a Mach port with a send or send-once right (mach_port_t).
|
||||
* The mask is a mask of desired events from dispatch_source_mach_send_flags_t.
|
||||
*/
|
||||
#define DISPATCH_SOURCE_TYPE_MACH_SEND (&_dispatch_source_type_mach_send)
|
||||
API_AVAILABLE(macos(10.6), ios(4.0)) DISPATCH_LINUX_UNAVAILABLE()
|
||||
DISPATCH_SOURCE_TYPE_DECL(mach_send);
|
||||
|
||||
/*!
|
||||
* @const DISPATCH_SOURCE_TYPE_MACH_RECV
|
||||
* @discussion A dispatch source that monitors a Mach port for pending messages.
|
||||
* The handle is a Mach port with a receive right (mach_port_t).
|
||||
* The mask is unused (pass zero for now).
|
||||
*/
|
||||
#define DISPATCH_SOURCE_TYPE_MACH_RECV (&_dispatch_source_type_mach_recv)
|
||||
API_AVAILABLE(macos(10.6), ios(4.0)) DISPATCH_LINUX_UNAVAILABLE()
|
||||
DISPATCH_SOURCE_TYPE_DECL(mach_recv);
|
||||
|
||||
/*!
|
||||
* @const DISPATCH_SOURCE_TYPE_MEMORYPRESSURE
|
||||
* @discussion A dispatch source that monitors the system for changes in
|
||||
* memory pressure condition.
|
||||
* The handle is unused (pass zero for now).
|
||||
* The mask is a mask of desired events from
|
||||
* dispatch_source_memorypressure_flags_t.
|
||||
*/
|
||||
#define DISPATCH_SOURCE_TYPE_MEMORYPRESSURE \
|
||||
(&_dispatch_source_type_memorypressure)
|
||||
API_AVAILABLE(macos(10.9), ios(8.0)) DISPATCH_LINUX_UNAVAILABLE()
|
||||
DISPATCH_SOURCE_TYPE_DECL(memorypressure);
|
||||
|
||||
/*!
|
||||
* @const DISPATCH_SOURCE_TYPE_PROC
|
||||
* @discussion A dispatch source that monitors an external process for events
|
||||
* defined by dispatch_source_proc_flags_t.
|
||||
* The handle is a process identifier (pid_t).
|
||||
* The mask is a mask of desired events from dispatch_source_proc_flags_t.
|
||||
*/
|
||||
#define DISPATCH_SOURCE_TYPE_PROC (&_dispatch_source_type_proc)
|
||||
API_AVAILABLE(macos(10.6), ios(4.0)) DISPATCH_LINUX_UNAVAILABLE()
|
||||
DISPATCH_SOURCE_TYPE_DECL(proc);
|
||||
|
||||
/*!
|
||||
* @const DISPATCH_SOURCE_TYPE_READ
|
||||
* @discussion A dispatch source that monitors a file descriptor for pending
|
||||
* bytes available to be read.
|
||||
* The handle is a file descriptor (int).
|
||||
* The mask is unused (pass zero for now).
|
||||
*/
|
||||
#define DISPATCH_SOURCE_TYPE_READ (&_dispatch_source_type_read)
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_SOURCE_TYPE_DECL(read);
|
||||
|
||||
/*!
|
||||
* @const DISPATCH_SOURCE_TYPE_SIGNAL
|
||||
* @discussion A dispatch source that monitors the current process for signals.
|
||||
* The handle is a signal number (int).
|
||||
* The mask is unused (pass zero for now).
|
||||
*/
|
||||
#define DISPATCH_SOURCE_TYPE_SIGNAL (&_dispatch_source_type_signal)
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_SOURCE_TYPE_DECL(signal);
|
||||
|
||||
/*!
|
||||
* @const DISPATCH_SOURCE_TYPE_TIMER
|
||||
* @discussion A dispatch source that submits the event handler block based
|
||||
* on a timer.
|
||||
* The handle is unused (pass zero for now).
|
||||
* The mask specifies which flags from dispatch_source_timer_flags_t to apply.
|
||||
*/
|
||||
#define DISPATCH_SOURCE_TYPE_TIMER (&_dispatch_source_type_timer)
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_SOURCE_TYPE_DECL(timer);
|
||||
|
||||
/*!
|
||||
* @const DISPATCH_SOURCE_TYPE_VNODE
|
||||
* @discussion A dispatch source that monitors a file descriptor for events
|
||||
* defined by dispatch_source_vnode_flags_t.
|
||||
* The handle is a file descriptor (int).
|
||||
* The mask is a mask of desired events from dispatch_source_vnode_flags_t.
|
||||
*/
|
||||
#define DISPATCH_SOURCE_TYPE_VNODE (&_dispatch_source_type_vnode)
|
||||
API_AVAILABLE(macos(10.6), ios(4.0)) DISPATCH_LINUX_UNAVAILABLE()
|
||||
DISPATCH_SOURCE_TYPE_DECL(vnode);
|
||||
|
||||
/*!
|
||||
* @const DISPATCH_SOURCE_TYPE_WRITE
|
||||
* @discussion A dispatch source that monitors a file descriptor for available
|
||||
* buffer space to write bytes.
|
||||
* The handle is a file descriptor (int).
|
||||
* The mask is unused (pass zero for now).
|
||||
*/
|
||||
#define DISPATCH_SOURCE_TYPE_WRITE (&_dispatch_source_type_write)
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_SOURCE_TYPE_DECL(write);
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_source_mach_send_flags_t
|
||||
* Type of dispatch_source_mach_send flags
|
||||
*
|
||||
* @constant DISPATCH_MACH_SEND_DEAD
|
||||
* The receive right corresponding to the given send right was destroyed.
|
||||
*/
|
||||
#define DISPATCH_MACH_SEND_DEAD 0x1
|
||||
|
||||
typedef unsigned long dispatch_source_mach_send_flags_t;
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_source_memorypressure_flags_t
|
||||
* Type of dispatch_source_memorypressure flags
|
||||
*
|
||||
* @constant DISPATCH_MEMORYPRESSURE_NORMAL
|
||||
* The system memory pressure condition has returned to normal.
|
||||
*
|
||||
* @constant DISPATCH_MEMORYPRESSURE_WARN
|
||||
* The system memory pressure condition has changed to warning.
|
||||
*
|
||||
* @constant DISPATCH_MEMORYPRESSURE_CRITICAL
|
||||
* The system memory pressure condition has changed to critical.
|
||||
*
|
||||
* @discussion
|
||||
* Elevated memory pressure is a system-wide condition that applications
|
||||
* registered for this source should react to by changing their future memory
|
||||
* use behavior, e.g. by reducing cache sizes of newly initiated operations
|
||||
* until memory pressure returns back to normal.
|
||||
* NOTE: applications should NOT traverse and discard existing caches for past
|
||||
* operations when the system memory pressure enters an elevated state, as that
|
||||
* is likely to trigger VM operations that will further aggravate system memory
|
||||
* pressure.
|
||||
*/
|
||||
|
||||
#define DISPATCH_MEMORYPRESSURE_NORMAL 0x01
|
||||
#define DISPATCH_MEMORYPRESSURE_WARN 0x02
|
||||
#define DISPATCH_MEMORYPRESSURE_CRITICAL 0x04
|
||||
|
||||
typedef unsigned long dispatch_source_memorypressure_flags_t;
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_source_proc_flags_t
|
||||
* Type of dispatch_source_proc flags
|
||||
*
|
||||
* @constant DISPATCH_PROC_EXIT
|
||||
* The process has exited (perhaps cleanly, perhaps not).
|
||||
*
|
||||
* @constant DISPATCH_PROC_FORK
|
||||
* The process has created one or more child processes.
|
||||
*
|
||||
* @constant DISPATCH_PROC_EXEC
|
||||
* The process has become another executable image via
|
||||
* exec*() or posix_spawn*().
|
||||
*
|
||||
* @constant DISPATCH_PROC_SIGNAL
|
||||
* A Unix signal was delivered to the process.
|
||||
*/
|
||||
#define DISPATCH_PROC_EXIT 0x80000000
|
||||
#define DISPATCH_PROC_FORK 0x40000000
|
||||
#define DISPATCH_PROC_EXEC 0x20000000
|
||||
#define DISPATCH_PROC_SIGNAL 0x08000000
|
||||
|
||||
typedef unsigned long dispatch_source_proc_flags_t;
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_source_vnode_flags_t
|
||||
* Type of dispatch_source_vnode flags
|
||||
*
|
||||
* @constant DISPATCH_VNODE_DELETE
|
||||
* The filesystem object was deleted from the namespace.
|
||||
*
|
||||
* @constant DISPATCH_VNODE_WRITE
|
||||
* The filesystem object data changed.
|
||||
*
|
||||
* @constant DISPATCH_VNODE_EXTEND
|
||||
* The filesystem object changed in size.
|
||||
*
|
||||
* @constant DISPATCH_VNODE_ATTRIB
|
||||
* The filesystem object metadata changed.
|
||||
*
|
||||
* @constant DISPATCH_VNODE_LINK
|
||||
* The filesystem object link count changed.
|
||||
*
|
||||
* @constant DISPATCH_VNODE_RENAME
|
||||
* The filesystem object was renamed in the namespace.
|
||||
*
|
||||
* @constant DISPATCH_VNODE_REVOKE
|
||||
* The filesystem object was revoked.
|
||||
*
|
||||
* @constant DISPATCH_VNODE_FUNLOCK
|
||||
* The filesystem object was unlocked.
|
||||
*/
|
||||
|
||||
#define DISPATCH_VNODE_DELETE 0x1
|
||||
#define DISPATCH_VNODE_WRITE 0x2
|
||||
#define DISPATCH_VNODE_EXTEND 0x4
|
||||
#define DISPATCH_VNODE_ATTRIB 0x8
|
||||
#define DISPATCH_VNODE_LINK 0x10
|
||||
#define DISPATCH_VNODE_RENAME 0x20
|
||||
#define DISPATCH_VNODE_REVOKE 0x40
|
||||
#define DISPATCH_VNODE_FUNLOCK 0x100
|
||||
|
||||
typedef unsigned long dispatch_source_vnode_flags_t;
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_source_timer_flags_t
|
||||
* Type of dispatch_source_timer flags
|
||||
*
|
||||
* @constant DISPATCH_TIMER_STRICT
|
||||
* Specifies that the system should make a best effort to strictly observe the
|
||||
* leeway value specified for the timer via dispatch_source_set_timer(), even
|
||||
* if that value is smaller than the default leeway value that would be applied
|
||||
* to the timer otherwise. A minimal amount of leeway will be applied to the
|
||||
* timer even if this flag is specified.
|
||||
*
|
||||
* CAUTION: Use of this flag may override power-saving techniques employed by
|
||||
* the system and cause higher power consumption, so it must be used with care
|
||||
* and only when absolutely necessary.
|
||||
*/
|
||||
|
||||
#define DISPATCH_TIMER_STRICT 0x1
|
||||
|
||||
typedef unsigned long dispatch_source_timer_flags_t;
|
||||
|
||||
/*!
|
||||
* @function dispatch_source_create
|
||||
*
|
||||
* @abstract
|
||||
* Creates a new dispatch source to monitor low-level system objects and auto-
|
||||
* matically submit a handler block to a dispatch queue in response to events.
|
||||
*
|
||||
* @discussion
|
||||
* Dispatch sources are not reentrant. Any events received while the dispatch
|
||||
* source is suspended or while the event handler block is currently executing
|
||||
* will be coalesced and delivered after the dispatch source is resumed or the
|
||||
* event handler block has returned.
|
||||
*
|
||||
* Dispatch sources are created in an inactive state. After creating the
|
||||
* source and setting any desired attributes (i.e. the handler, context, etc.),
|
||||
* a call must be made to dispatch_activate() in order to begin event delivery.
|
||||
*
|
||||
* Calling dispatch_set_target_queue() on a source once it has been activated
|
||||
* is not allowed (see dispatch_activate() and dispatch_set_target_queue()).
|
||||
*
|
||||
* For backward compatibility reasons, dispatch_resume() on an inactive,
|
||||
* and not otherwise suspended source has the same effect as calling
|
||||
* dispatch_activate(). For new code, using dispatch_activate() is preferred.
|
||||
*
|
||||
* @param type
|
||||
* Declares the type of the dispatch source. Must be one of the defined
|
||||
* dispatch_source_type_t constants.
|
||||
*
|
||||
* @param handle
|
||||
* The underlying system handle to monitor. The interpretation of this argument
|
||||
* is determined by the constant provided in the type parameter.
|
||||
*
|
||||
* @param mask
|
||||
* A mask of flags specifying which events are desired. The interpretation of
|
||||
* this argument is determined by the constant provided in the type parameter.
|
||||
*
|
||||
* @param queue
|
||||
* The dispatch queue to which the event handler block will be submitted.
|
||||
* If queue is DISPATCH_TARGET_QUEUE_DEFAULT, the source will submit the event
|
||||
* handler block to the default priority global queue.
|
||||
*
|
||||
* @result
|
||||
* The newly created dispatch source. Or NULL if invalid arguments are passed.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
|
||||
DISPATCH_NOTHROW
|
||||
dispatch_source_t
|
||||
dispatch_source_create(dispatch_source_type_t type,
|
||||
uintptr_t handle,
|
||||
uintptr_t mask,
|
||||
dispatch_queue_t _Nullable queue);
|
||||
|
||||
/*!
|
||||
* @function dispatch_source_set_event_handler
|
||||
*
|
||||
* @abstract
|
||||
* Sets the event handler block for the given dispatch source.
|
||||
*
|
||||
* @param source
|
||||
* The dispatch source to modify.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @param handler
|
||||
* The event handler block to submit to the source's target queue.
|
||||
*/
|
||||
#ifdef __BLOCKS__
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_source_set_event_handler(dispatch_source_t source,
|
||||
dispatch_block_t _Nullable handler);
|
||||
#endif /* __BLOCKS__ */
|
||||
|
||||
/*!
|
||||
* @function dispatch_source_set_event_handler_f
|
||||
*
|
||||
* @abstract
|
||||
* Sets the event handler function for the given dispatch source.
|
||||
*
|
||||
* @param source
|
||||
* The dispatch source to modify.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @param handler
|
||||
* The event handler function to submit to the source's target queue.
|
||||
* The context parameter passed to the event handler function is the context of
|
||||
* the dispatch source current at the time the event handler was set.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_source_set_event_handler_f(dispatch_source_t source,
|
||||
dispatch_function_t _Nullable handler);
|
||||
|
||||
/*!
|
||||
* @function dispatch_source_set_cancel_handler
|
||||
*
|
||||
* @abstract
|
||||
* Sets the cancellation handler block for the given dispatch source.
|
||||
*
|
||||
* @discussion
|
||||
* The cancellation handler (if specified) will be submitted to the source's
|
||||
* target queue in response to a call to dispatch_source_cancel() once the
|
||||
* system has released all references to the source's underlying handle and
|
||||
* the source's event handler block has returned.
|
||||
*
|
||||
* IMPORTANT:
|
||||
* Source cancellation and a cancellation handler are required for file
|
||||
* descriptor and mach port based sources in order to safely close the
|
||||
* descriptor or destroy the port.
|
||||
* Closing the descriptor or port before the cancellation handler is invoked may
|
||||
* result in a race condition. If a new descriptor is allocated with the same
|
||||
* value as the recently closed descriptor while the source's event handler is
|
||||
* still running, the event handler may read/write data to the wrong descriptor.
|
||||
*
|
||||
* @param source
|
||||
* The dispatch source to modify.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @param handler
|
||||
* The cancellation handler block to submit to the source's target queue.
|
||||
*/
|
||||
#ifdef __BLOCKS__
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_source_set_cancel_handler(dispatch_source_t source,
|
||||
dispatch_block_t _Nullable handler);
|
||||
#endif /* __BLOCKS__ */
|
||||
|
||||
/*!
|
||||
* @function dispatch_source_set_cancel_handler_f
|
||||
*
|
||||
* @abstract
|
||||
* Sets the cancellation handler function for the given dispatch source.
|
||||
*
|
||||
* @discussion
|
||||
* See dispatch_source_set_cancel_handler() for more details.
|
||||
*
|
||||
* @param source
|
||||
* The dispatch source to modify.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @param handler
|
||||
* The cancellation handler function to submit to the source's target queue.
|
||||
* The context parameter passed to the event handler function is the current
|
||||
* context of the dispatch source at the time the handler call is made.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_source_set_cancel_handler_f(dispatch_source_t source,
|
||||
dispatch_function_t _Nullable handler);
|
||||
|
||||
/*!
|
||||
* @function dispatch_source_cancel
|
||||
*
|
||||
* @abstract
|
||||
* Asynchronously cancel the dispatch source, preventing any further invocation
|
||||
* of its event handler block.
|
||||
*
|
||||
* @discussion
|
||||
* Cancellation prevents any further invocation of the event handler block for
|
||||
* the specified dispatch source, but does not interrupt an event handler
|
||||
* block that is already in progress.
|
||||
*
|
||||
* The cancellation handler is submitted to the source's target queue once the
|
||||
* the source's event handler has finished, indicating it is now safe to close
|
||||
* the source's handle (i.e. file descriptor or mach port).
|
||||
*
|
||||
* See dispatch_source_set_cancel_handler() for more information.
|
||||
*
|
||||
* @param source
|
||||
* The dispatch source to be canceled.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_source_cancel(dispatch_source_t source);
|
||||
|
||||
/*!
|
||||
* @function dispatch_source_testcancel
|
||||
*
|
||||
* @abstract
|
||||
* Tests whether the given dispatch source has been canceled.
|
||||
*
|
||||
* @param source
|
||||
* The dispatch source to be tested.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @result
|
||||
* Non-zero if canceled and zero if not canceled.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_WARN_RESULT DISPATCH_PURE
|
||||
DISPATCH_NOTHROW
|
||||
intptr_t
|
||||
dispatch_source_testcancel(dispatch_source_t source);
|
||||
|
||||
/*!
|
||||
* @function dispatch_source_get_handle
|
||||
*
|
||||
* @abstract
|
||||
* Returns the underlying system handle associated with this dispatch source.
|
||||
*
|
||||
* @param source
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @result
|
||||
* The return value should be interpreted according to the type of the dispatch
|
||||
* source, and may be one of the following handles:
|
||||
*
|
||||
* DISPATCH_SOURCE_TYPE_DATA_ADD: n/a
|
||||
* DISPATCH_SOURCE_TYPE_DATA_OR: n/a
|
||||
* DISPATCH_SOURCE_TYPE_DATA_REPLACE: n/a
|
||||
* DISPATCH_SOURCE_TYPE_MACH_SEND: mach port (mach_port_t)
|
||||
* DISPATCH_SOURCE_TYPE_MACH_RECV: mach port (mach_port_t)
|
||||
* DISPATCH_SOURCE_TYPE_MEMORYPRESSURE n/a
|
||||
* DISPATCH_SOURCE_TYPE_PROC: process identifier (pid_t)
|
||||
* DISPATCH_SOURCE_TYPE_READ: file descriptor (int)
|
||||
* DISPATCH_SOURCE_TYPE_SIGNAL: signal number (int)
|
||||
* DISPATCH_SOURCE_TYPE_TIMER: n/a
|
||||
* DISPATCH_SOURCE_TYPE_VNODE: file descriptor (int)
|
||||
* DISPATCH_SOURCE_TYPE_WRITE: file descriptor (int)
|
||||
*/
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_WARN_RESULT DISPATCH_PURE
|
||||
DISPATCH_NOTHROW
|
||||
uintptr_t
|
||||
dispatch_source_get_handle(dispatch_source_t source);
|
||||
|
||||
/*!
|
||||
* @function dispatch_source_get_mask
|
||||
*
|
||||
* @abstract
|
||||
* Returns the mask of events monitored by the dispatch source.
|
||||
*
|
||||
* @param source
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @result
|
||||
* The return value should be interpreted according to the type of the dispatch
|
||||
* source, and may be one of the following flag sets:
|
||||
*
|
||||
* DISPATCH_SOURCE_TYPE_DATA_ADD: n/a
|
||||
* DISPATCH_SOURCE_TYPE_DATA_OR: n/a
|
||||
* DISPATCH_SOURCE_TYPE_DATA_REPLACE: n/a
|
||||
* DISPATCH_SOURCE_TYPE_MACH_SEND: dispatch_source_mach_send_flags_t
|
||||
* DISPATCH_SOURCE_TYPE_MACH_RECV: n/a
|
||||
* DISPATCH_SOURCE_TYPE_MEMORYPRESSURE dispatch_source_memorypressure_flags_t
|
||||
* DISPATCH_SOURCE_TYPE_PROC: dispatch_source_proc_flags_t
|
||||
* DISPATCH_SOURCE_TYPE_READ: n/a
|
||||
* DISPATCH_SOURCE_TYPE_SIGNAL: n/a
|
||||
* DISPATCH_SOURCE_TYPE_TIMER: dispatch_source_timer_flags_t
|
||||
* DISPATCH_SOURCE_TYPE_VNODE: dispatch_source_vnode_flags_t
|
||||
* DISPATCH_SOURCE_TYPE_WRITE: n/a
|
||||
*/
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_WARN_RESULT DISPATCH_PURE
|
||||
DISPATCH_NOTHROW
|
||||
uintptr_t
|
||||
dispatch_source_get_mask(dispatch_source_t source);
|
||||
|
||||
/*!
|
||||
* @function dispatch_source_get_data
|
||||
*
|
||||
* @abstract
|
||||
* Returns pending data for the dispatch source.
|
||||
*
|
||||
* @discussion
|
||||
* This function is intended to be called from within the event handler block.
|
||||
* The result of calling this function outside of the event handler callback is
|
||||
* undefined.
|
||||
*
|
||||
* @param source
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @result
|
||||
* The return value should be interpreted according to the type of the dispatch
|
||||
* source, and may be one of the following:
|
||||
*
|
||||
* DISPATCH_SOURCE_TYPE_DATA_ADD: application defined data
|
||||
* DISPATCH_SOURCE_TYPE_DATA_OR: application defined data
|
||||
* DISPATCH_SOURCE_TYPE_DATA_REPLACE: application defined data
|
||||
* DISPATCH_SOURCE_TYPE_MACH_SEND: dispatch_source_mach_send_flags_t
|
||||
* DISPATCH_SOURCE_TYPE_MACH_RECV: n/a
|
||||
* DISPATCH_SOURCE_TYPE_MEMORYPRESSURE dispatch_source_memorypressure_flags_t
|
||||
* DISPATCH_SOURCE_TYPE_PROC: dispatch_source_proc_flags_t
|
||||
* DISPATCH_SOURCE_TYPE_READ: estimated bytes available to read
|
||||
* DISPATCH_SOURCE_TYPE_SIGNAL: number of signals delivered since
|
||||
* the last handler invocation
|
||||
* DISPATCH_SOURCE_TYPE_TIMER: number of times the timer has fired
|
||||
* since the last handler invocation
|
||||
* DISPATCH_SOURCE_TYPE_VNODE: dispatch_source_vnode_flags_t
|
||||
* DISPATCH_SOURCE_TYPE_WRITE: estimated buffer space available
|
||||
*/
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_WARN_RESULT DISPATCH_PURE
|
||||
DISPATCH_NOTHROW
|
||||
uintptr_t
|
||||
dispatch_source_get_data(dispatch_source_t source);
|
||||
|
||||
/*!
|
||||
* @function dispatch_source_merge_data
|
||||
*
|
||||
* @abstract
|
||||
* Merges data into a dispatch source of type DISPATCH_SOURCE_TYPE_DATA_ADD,
|
||||
* DISPATCH_SOURCE_TYPE_DATA_OR or DISPATCH_SOURCE_TYPE_DATA_REPLACE,
|
||||
* and submits its event handler block to its target queue.
|
||||
*
|
||||
* @param source
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @param value
|
||||
* The value to coalesce with the pending data using a logical OR or an ADD
|
||||
* as specified by the dispatch source type. A value of zero has no effect
|
||||
* and will not result in the submission of the event handler block.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_source_merge_data(dispatch_source_t source, uintptr_t value);
|
||||
|
||||
/*!
|
||||
* @function dispatch_source_set_timer
|
||||
*
|
||||
* @abstract
|
||||
* Sets a start time, interval, and leeway value for a timer source.
|
||||
*
|
||||
* @discussion
|
||||
* Once this function returns, any pending source data accumulated for the
|
||||
* previous timer values has been cleared; the next fire of the timer will
|
||||
* occur at 'start', and every 'interval' nanoseconds thereafter until the
|
||||
* timer source is canceled.
|
||||
*
|
||||
* Any fire of the timer may be delayed by the system in order to improve power
|
||||
* consumption and system performance. The upper limit to the allowable delay
|
||||
* may be configured with the 'leeway' argument, the lower limit is under the
|
||||
* control of the system.
|
||||
*
|
||||
* For the initial timer fire at 'start', the upper limit to the allowable
|
||||
* delay is set to 'leeway' nanoseconds. For the subsequent timer fires at
|
||||
* 'start' + N * 'interval', the upper limit is MIN('leeway','interval'/2).
|
||||
*
|
||||
* The lower limit to the allowable delay may vary with process state such as
|
||||
* visibility of application UI. If the specified timer source was created with
|
||||
* a mask of DISPATCH_TIMER_STRICT, the system will make a best effort to
|
||||
* strictly observe the provided 'leeway' value even if it is smaller than the
|
||||
* current lower limit. Note that a minimal amount of delay is to be expected
|
||||
* even if this flag is specified.
|
||||
*
|
||||
* The 'start' argument also determines which clock will be used for the timer:
|
||||
* If 'start' is DISPATCH_TIME_NOW or was created with dispatch_time(3), the
|
||||
* timer is based on up time (which is obtained from mach_absolute_time() on
|
||||
* Apple platforms). If 'start' was created with dispatch_walltime(3), the
|
||||
* timer is based on gettimeofday(3).
|
||||
*
|
||||
* Calling this function has no effect if the timer source has already been
|
||||
* canceled.
|
||||
*
|
||||
* @param start
|
||||
* The start time of the timer. See dispatch_time() and dispatch_walltime()
|
||||
* for more information.
|
||||
*
|
||||
* @param interval
|
||||
* The nanosecond interval for the timer. Use DISPATCH_TIME_FOREVER for a
|
||||
* one-shot timer.
|
||||
*
|
||||
* @param leeway
|
||||
* The nanosecond leeway for the timer.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_source_set_timer(dispatch_source_t source,
|
||||
dispatch_time_t start,
|
||||
uint64_t interval,
|
||||
uint64_t leeway);
|
||||
|
||||
/*!
|
||||
* @function dispatch_source_set_registration_handler
|
||||
*
|
||||
* @abstract
|
||||
* Sets the registration handler block for the given dispatch source.
|
||||
*
|
||||
* @discussion
|
||||
* The registration handler (if specified) will be submitted to the source's
|
||||
* target queue once the corresponding kevent() has been registered with the
|
||||
* system, following the initial dispatch_resume() of the source.
|
||||
*
|
||||
* If a source is already registered when the registration handler is set, the
|
||||
* registration handler will be invoked immediately.
|
||||
*
|
||||
* @param source
|
||||
* The dispatch source to modify.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @param handler
|
||||
* The registration handler block to submit to the source's target queue.
|
||||
*/
|
||||
#ifdef __BLOCKS__
|
||||
API_AVAILABLE(macos(10.7), ios(4.3))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_source_set_registration_handler(dispatch_source_t source,
|
||||
dispatch_block_t _Nullable handler);
|
||||
#endif /* __BLOCKS__ */
|
||||
|
||||
/*!
|
||||
* @function dispatch_source_set_registration_handler_f
|
||||
*
|
||||
* @abstract
|
||||
* Sets the registration handler function for the given dispatch source.
|
||||
*
|
||||
* @discussion
|
||||
* See dispatch_source_set_registration_handler() for more details.
|
||||
*
|
||||
* @param source
|
||||
* The dispatch source to modify.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @param handler
|
||||
* The registration handler function to submit to the source's target queue.
|
||||
* The context parameter passed to the registration handler function is the
|
||||
* current context of the dispatch source at the time the handler call is made.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.7), ios(4.3))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_source_set_registration_handler_f(dispatch_source_t source,
|
||||
dispatch_function_t _Nullable handler);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_END
|
||||
|
||||
#endif /* __DISPATCH_SOURCE__ */
|
||||
135
Telegram/ThirdParty/dispatch/dispatch/time.h
vendored
Normal file
135
Telegram/ThirdParty/dispatch/dispatch/time.h
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2011 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#ifndef __DISPATCH_TIME__
|
||||
#define __DISPATCH_TIME__
|
||||
|
||||
#ifndef __DISPATCH_INDIRECT__
|
||||
#error "Please #include <dispatch/dispatch.h> instead of this file directly."
|
||||
#include <dispatch/base.h> // for HeaderDoc
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// <rdar://problem/6368156&7563559>
|
||||
#if TARGET_OS_MAC
|
||||
#include <mach/clock_types.h>
|
||||
#endif
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_BEGIN
|
||||
|
||||
#ifdef NSEC_PER_SEC
|
||||
#undef NSEC_PER_SEC
|
||||
#endif
|
||||
#ifdef USEC_PER_SEC
|
||||
#undef USEC_PER_SEC
|
||||
#endif
|
||||
#ifdef NSEC_PER_USEC
|
||||
#undef NSEC_PER_USEC
|
||||
#endif
|
||||
#ifdef NSEC_PER_MSEC
|
||||
#undef NSEC_PER_MSEC
|
||||
#endif
|
||||
#define NSEC_PER_SEC 1000000000ull
|
||||
#define NSEC_PER_MSEC 1000000ull
|
||||
#define USEC_PER_SEC 1000000ull
|
||||
#define NSEC_PER_USEC 1000ull
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
struct timespec;
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_time_t
|
||||
*
|
||||
* @abstract
|
||||
* A somewhat abstract representation of time; where zero means "now" and
|
||||
* DISPATCH_TIME_FOREVER means "infinity" and every value in between is an
|
||||
* opaque encoding.
|
||||
*/
|
||||
typedef uint64_t dispatch_time_t;
|
||||
|
||||
enum {
|
||||
DISPATCH_WALLTIME_NOW DISPATCH_ENUM_API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0)) = ~1ull,
|
||||
};
|
||||
|
||||
#define DISPATCH_TIME_NOW (0ull)
|
||||
#define DISPATCH_TIME_FOREVER (~0ull)
|
||||
|
||||
/*!
|
||||
* @function dispatch_time
|
||||
*
|
||||
* @abstract
|
||||
* Create a dispatch_time_t relative to the current value of the default or
|
||||
* wall time clock, or modify an existing dispatch_time_t.
|
||||
*
|
||||
* @discussion
|
||||
* On Apple platforms, the default clock is based on mach_absolute_time().
|
||||
*
|
||||
* @param when
|
||||
* An optional dispatch_time_t to add nanoseconds to. If DISPATCH_TIME_NOW is
|
||||
* passed, then dispatch_time() will use the default clock (which is based on
|
||||
* mach_absolute_time() on Apple platforms). If DISPATCH_WALLTIME_NOW is used,
|
||||
* dispatch_time() will use the value returned by gettimeofday(3).
|
||||
* dispatch_time(DISPATCH_WALLTIME_NOW, delta) is equivalent to
|
||||
* dispatch_walltime(NULL, delta).
|
||||
*
|
||||
* @param delta
|
||||
* Nanoseconds to add.
|
||||
*
|
||||
* @result
|
||||
* A new dispatch_time_t.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_WARN_RESULT DISPATCH_NOTHROW
|
||||
dispatch_time_t
|
||||
dispatch_time(dispatch_time_t when, int64_t delta);
|
||||
|
||||
/*!
|
||||
* @function dispatch_walltime
|
||||
*
|
||||
* @abstract
|
||||
* Create a dispatch_time_t using the wall clock.
|
||||
*
|
||||
* @discussion
|
||||
* On Mac OS X the wall clock is based on gettimeofday(3).
|
||||
*
|
||||
* @param when
|
||||
* A struct timespec to add time to. If NULL is passed, then
|
||||
* dispatch_walltime() will use the result of gettimeofday(3).
|
||||
* dispatch_walltime(NULL, delta) returns the same value as
|
||||
* dispatch_time(DISPATCH_WALLTIME_NOW, delta).
|
||||
*
|
||||
* @param delta
|
||||
* Nanoseconds to add.
|
||||
*
|
||||
* @result
|
||||
* A new dispatch_time_t.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_WARN_RESULT DISPATCH_NOTHROW
|
||||
dispatch_time_t
|
||||
dispatch_walltime(const struct timespec *_Nullable when, int64_t delta);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_END
|
||||
|
||||
#endif /* __DISPATCH_TIME__ */
|
||||
23
Telegram/ThirdParty/dispatch/man/CMakeLists.txt
vendored
Normal file
23
Telegram/ThirdParty/dispatch/man/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
|
||||
# TODO(compnerd) add symlinks
|
||||
if(NOT ENABLE_SWIFT)
|
||||
install(FILES
|
||||
dispatch.3
|
||||
dispatch_after.3
|
||||
dispatch_api.3
|
||||
dispatch_apply.3
|
||||
dispatch_async.3
|
||||
dispatch_data_create.3
|
||||
dispatch_group_create.3
|
||||
dispatch_io_create.3
|
||||
dispatch_io_read.3
|
||||
dispatch_object.3
|
||||
dispatch_once.3
|
||||
dispatch_queue_create.3
|
||||
dispatch_read.3
|
||||
dispatch_semaphore_create.3
|
||||
dispatch_source_create.3
|
||||
dispatch_time.3
|
||||
DESTINATION
|
||||
"${CMAKE_INSTALL_FULL_MANDIR}/man3")
|
||||
endif()
|
||||
43
Telegram/ThirdParty/dispatch/man/dispatch.3
vendored
Normal file
43
Telegram/ThirdParty/dispatch/man/dispatch.3
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
.\" Copyright (c) 2008-2012 Apple Inc. All rights reserved.
|
||||
.Dd May 1, 2009
|
||||
.Dt dispatch 3
|
||||
.Os Darwin
|
||||
.Sh NAME
|
||||
.Nm dispatch
|
||||
.Nd the dispatch framework
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <dispatch/dispatch.h>
|
||||
.Sh DESCRIPTION
|
||||
The dispatch framework allows blocks to be scheduled for asynchronous and
|
||||
concurrent execution via the core functions described in
|
||||
.Xr dispatch_async 3 and
|
||||
.Xr dispatch_apply 3 .
|
||||
.Pp
|
||||
Dispatch queues are the basic units of organization of blocks. Several queues
|
||||
are created by default, and applications may create additional queues for their
|
||||
own use. See
|
||||
.Xr dispatch_queue_create 3
|
||||
for more information.
|
||||
.Pp
|
||||
Dispatch groups allow applications to track the progress of blocks submitted to
|
||||
queues and take action when the blocks complete. See
|
||||
.Xr dispatch_group_create 3
|
||||
for more information.
|
||||
.Pp
|
||||
The dispatch framework also provides functions to monitor underlying system
|
||||
events and automatically submit event handler blocks to dispatch queues.
|
||||
.Sh SEE ALSO
|
||||
.Xr dispatch_after 3 ,
|
||||
.Xr dispatch_api 3 ,
|
||||
.Xr dispatch_apply 3 ,
|
||||
.Xr dispatch_async 3 ,
|
||||
.Xr dispatch_data_create 3 ,
|
||||
.Xr dispatch_group_create 3 ,
|
||||
.Xr dispatch_io_create 3 ,
|
||||
.Xr dispatch_io_read 3 ,
|
||||
.Xr dispatch_object 3 ,
|
||||
.Xr dispatch_once 3 ,
|
||||
.Xr dispatch_queue_create 3 ,
|
||||
.Xr dispatch_semaphore_create 3 ,
|
||||
.Xr dispatch_source_create 3 ,
|
||||
.Xr dispatch_time 3
|
||||
69
Telegram/ThirdParty/dispatch/man/dispatch_after.3
vendored
Normal file
69
Telegram/ThirdParty/dispatch/man/dispatch_after.3
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
.\" Copyright (c) 2008-2010 Apple Inc. All rights reserved.
|
||||
.Dd May 1, 2009
|
||||
.Dt dispatch_after 3
|
||||
.Os Darwin
|
||||
.Sh NAME
|
||||
.Nm dispatch_after
|
||||
.Nd schedule blocks for deferred execution
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <dispatch/dispatch.h>
|
||||
.Ft void
|
||||
.Fo dispatch_after
|
||||
.Fa "dispatch_time_t when" "dispatch_queue_t queue" "void (^block)(void)"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_after_f
|
||||
.Fa "dispatch_time_t when" "dispatch_queue_t queue" "void *context" "void (*function)(void *)"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn dispatch_after
|
||||
function submits the
|
||||
.Fa block
|
||||
to the given
|
||||
.Fa queue
|
||||
at the time specified by the
|
||||
.Fa when
|
||||
parameter.
|
||||
The
|
||||
.Fa when
|
||||
parameter is a value created by
|
||||
.Fn dispatch_time
|
||||
or
|
||||
.Fn dispatch_walltime .
|
||||
Submission of the block may be delayed by the system in order to improve power consumption and system performance.
|
||||
The system applies a leeway (see
|
||||
.Xr dispatch_source_set_timer 3 )
|
||||
that is equal to one tenth of the interval between
|
||||
.Fa when
|
||||
and the time at which the function is called, with the leeway capped to at least one millisecond and at most one minute.
|
||||
.Pp
|
||||
For a more detailed description about submitting blocks to queues, see
|
||||
.Xr dispatch_async 3 .
|
||||
.Sh CAVEATS
|
||||
.Fn dispatch_after
|
||||
retains the passed queue.
|
||||
.Pp
|
||||
Specifying
|
||||
.Vt DISPATCH_TIME_NOW
|
||||
as the
|
||||
.Fa when
|
||||
parameter
|
||||
is supported, but is not as efficient as calling
|
||||
.Fn dispatch_async .
|
||||
.Pp
|
||||
The result of passing
|
||||
.Vt DISPATCH_TIME_FOREVER
|
||||
as the
|
||||
.Fa when
|
||||
parameter is undefined.
|
||||
.Pp
|
||||
.Sh FUNDAMENTALS
|
||||
The
|
||||
.Fn dispatch_after
|
||||
function is a wrapper around
|
||||
.Fn dispatch_after_f .
|
||||
.Sh SEE ALSO
|
||||
.Xr dispatch 3 ,
|
||||
.Xr dispatch_async 3 ,
|
||||
.Xr dispatch_time 3
|
||||
44
Telegram/ThirdParty/dispatch/man/dispatch_api.3
vendored
Normal file
44
Telegram/ThirdParty/dispatch/man/dispatch_api.3
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
.\" Copyright (c) 2008-2009 Apple Inc. All rights reserved.
|
||||
.Dd May 1, 2009
|
||||
.Dt dispatch_api 3
|
||||
.Os Darwin
|
||||
.Sh NAME
|
||||
.Nm dispatch_api
|
||||
.Nd Designing API using dispatch
|
||||
.Sh DESCRIPTION
|
||||
The following is a brief summary of some of the common design patterns to
|
||||
consider when designing and implementing API in terms of dispatch queues
|
||||
and blocks.
|
||||
.Pp
|
||||
A general recommendation is to allow both a callback block and target dispatch
|
||||
queue to be specified. This gives the application the greatest flexibility in
|
||||
handling asynchronous events.
|
||||
.Pp
|
||||
It's also recommended that interfaces take only a single block as the last
|
||||
parameter. This is both for consistency across projects, as well as the visual
|
||||
aesthetics of multiline blocks that are declared inline. The dispatch queue to
|
||||
which the block will be submitted should immediately precede the block argument
|
||||
(second-to-last argument). For example:
|
||||
.Pp
|
||||
.Bd -literal -offset indent
|
||||
read_async(file, callback_queue, ^{
|
||||
printf("received callback.\\n");
|
||||
});
|
||||
.Ed
|
||||
.Pp
|
||||
When function pointer alternatives to interfaces that take blocks are provided,
|
||||
the argument order of the function signature should be identical to the block
|
||||
variant; with the exception that the block argument is replaced with a context
|
||||
pointer, and a new last parameter is added, which is the function to call.
|
||||
.Pp
|
||||
The function based callback should pass the context pointer as the first
|
||||
argument, and the subsequent arguments should be identical to the block based
|
||||
variant (albeit offset by one in order).
|
||||
.Pp
|
||||
It is also important to use consistent naming. The dispatch API, for example,
|
||||
uses the suffix "_f" for function based variants.
|
||||
.Pp
|
||||
.Sh SEE ALSO
|
||||
.Xr dispatch 3 ,
|
||||
.Xr dispatch_async 3 ,
|
||||
.Xr dispatch_queue_create 3
|
||||
122
Telegram/ThirdParty/dispatch/man/dispatch_apply.3
vendored
Normal file
122
Telegram/ThirdParty/dispatch/man/dispatch_apply.3
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
.\" Copyright (c) 2008-2017 Apple Inc. All rights reserved.
|
||||
.Dd May 1, 2009
|
||||
.Dt dispatch_apply 3
|
||||
.Os Darwin
|
||||
.Sh NAME
|
||||
.Nm dispatch_apply
|
||||
.Nd schedule blocks for iterative execution
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <dispatch/dispatch.h>
|
||||
.Ft void
|
||||
.Fo dispatch_apply
|
||||
.Fa "size_t iterations" "dispatch_queue_t queue" "void (^block)(size_t)"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_apply_f
|
||||
.Fa "size_t iterations" "dispatch_queue_t queue" "void *context" "void (*function)(void *, size_t)"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn dispatch_apply
|
||||
function provides data-level concurrency through a "for (;;)" loop like primitive:
|
||||
.Bd -literal
|
||||
size_t iterations = 10;
|
||||
|
||||
// 'idx' is zero indexed, just like:
|
||||
// for (idx = 0; idx < iterations; idx++)
|
||||
|
||||
dispatch_apply(iterations, DISPATCH_APPLY_AUTO, ^(size_t idx) {
|
||||
printf("%zu\\n", idx);
|
||||
});
|
||||
.Ed
|
||||
.Pp
|
||||
Although any queue can be used, it is strongly recommended to use
|
||||
.Vt DISPATCH_APPLY_AUTO
|
||||
as the
|
||||
.Vt queue
|
||||
argument to both
|
||||
.Fn dispatch_apply
|
||||
and
|
||||
.Fn dispatch_apply_f ,
|
||||
as shown in the example above, since this allows the system to automatically use worker threads
|
||||
that match the configuration of the current thread as closely as possible.
|
||||
No assumptions should be made about which global concurrent queue will be used.
|
||||
.Pp
|
||||
Like a "for (;;)" loop, the
|
||||
.Fn dispatch_apply
|
||||
function is synchronous.
|
||||
If asynchronous behavior is desired, wrap the call to
|
||||
.Fn dispatch_apply
|
||||
with a call to
|
||||
.Fn dispatch_async
|
||||
against another queue.
|
||||
.Pp
|
||||
Sometimes, when the block passed to
|
||||
.Fn dispatch_apply
|
||||
is simple, the use of striding can tune performance.
|
||||
Calculating the optimal stride is best left to experimentation.
|
||||
Start with a stride of one and work upwards until the desired performance is
|
||||
achieved (perhaps using a power of two search):
|
||||
.Bd -literal
|
||||
#define STRIDE 3
|
||||
|
||||
dispatch_apply(count / STRIDE, DISPATCH_APPLY_AUTO, ^(size_t idx) {
|
||||
size_t j = idx * STRIDE;
|
||||
size_t j_stop = j + STRIDE;
|
||||
do {
|
||||
printf("%zu\\n", j++);
|
||||
} while (j < j_stop);
|
||||
});
|
||||
|
||||
size_t i;
|
||||
for (i = count - (count % STRIDE); i < count; i++) {
|
||||
printf("%zu\\n", i);
|
||||
}
|
||||
.Ed
|
||||
.Sh IMPLIED REFERENCES
|
||||
Synchronous functions within the dispatch framework hold an implied reference
|
||||
on the target queue. In other words, the synchronous function borrows the
|
||||
reference of the calling function (this is valid because the calling function
|
||||
is blocked waiting for the result of the synchronous function, and therefore
|
||||
cannot modify the reference count of the target queue until after the
|
||||
synchronous function has returned).
|
||||
.Pp
|
||||
This is in contrast to asynchronous functions which must retain both the block
|
||||
and target queue for the duration of the asynchronous operation (as the calling
|
||||
function may immediately release its interest in these objects).
|
||||
.Sh FUNDAMENTALS
|
||||
.Fn dispatch_apply
|
||||
and
|
||||
.Fn dispatch_apply_f
|
||||
attempt to quickly create enough worker threads to efficiently iterate work in parallel.
|
||||
By contrast, a loop that passes work items individually to
|
||||
.Fn dispatch_async
|
||||
or
|
||||
.Fn dispatch_async_f
|
||||
will incur more overhead and does not express the desired parallel execution semantics to
|
||||
the system, so may not create an optimal number of worker threads for a parallel workload.
|
||||
For this reason, prefer to use
|
||||
.Fn dispatch_apply
|
||||
or
|
||||
.Fn dispatch_apply_f
|
||||
when parallel execution is important.
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_apply
|
||||
function is a wrapper around
|
||||
.Fn dispatch_apply_f .
|
||||
.Sh CAVEATS
|
||||
Unlike
|
||||
.Fn dispatch_async ,
|
||||
a block submitted to
|
||||
.Fn dispatch_apply
|
||||
is expected to be either independent or dependent
|
||||
.Em only
|
||||
on work already performed in lower-indexed invocations of the block. If
|
||||
the block's index dependency is non-linear, it is recommended to
|
||||
use a for-loop around invocations of
|
||||
.Fn dispatch_async .
|
||||
.Sh SEE ALSO
|
||||
.Xr dispatch 3 ,
|
||||
.Xr dispatch_async 3 ,
|
||||
.Xr dispatch_queue_create 3
|
||||
235
Telegram/ThirdParty/dispatch/man/dispatch_async.3
vendored
Normal file
235
Telegram/ThirdParty/dispatch/man/dispatch_async.3
vendored
Normal file
@@ -0,0 +1,235 @@
|
||||
.\" Copyright (c) 2008-2012 Apple Inc. All rights reserved.
|
||||
.Dd May 1, 2009
|
||||
.Dt dispatch_async 3
|
||||
.Os Darwin
|
||||
.Sh NAME
|
||||
.Nm dispatch_async ,
|
||||
.Nm dispatch_sync
|
||||
.Nd schedule blocks for execution
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <dispatch/dispatch.h>
|
||||
.Ft void
|
||||
.Fo dispatch_async
|
||||
.Fa "dispatch_queue_t queue" "void (^block)(void)"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_sync
|
||||
.Fa "dispatch_queue_t queue" "void (^block)(void)"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_async_f
|
||||
.Fa "dispatch_queue_t queue" "void *context" "void (*function)(void *)"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_sync_f
|
||||
.Fa "dispatch_queue_t queue" "void *context" "void (*function)(void *)"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn dispatch_async
|
||||
and
|
||||
.Fn dispatch_sync
|
||||
functions schedule blocks for concurrent execution within the
|
||||
.Xr dispatch 3
|
||||
framework. Blocks are submitted to a queue which dictates the policy for their
|
||||
execution. See
|
||||
.Xr dispatch_queue_create 3
|
||||
for more information about creating dispatch queues.
|
||||
.Pp
|
||||
These functions support efficient temporal synchronization, background
|
||||
concurrency and data-level concurrency. These same functions can also be used
|
||||
for efficient notification of the completion of asynchronous blocks (a.k.a.
|
||||
callbacks).
|
||||
.Sh TEMPORAL SYNCHRONIZATION
|
||||
Synchronization is often required when multiple threads of execution access
|
||||
shared data concurrently. The simplest form of synchronization is
|
||||
mutual-exclusion (a lock), whereby different subsystems execute concurrently
|
||||
until a shared critical section is entered. In the
|
||||
.Xr pthread 3
|
||||
family of procedures, temporal synchronization is accomplished like so:
|
||||
.Bd -literal -offset indent
|
||||
int r = pthread_mutex_lock(&my_lock);
|
||||
assert(r == 0);
|
||||
|
||||
// critical section
|
||||
|
||||
r = pthread_mutex_unlock(&my_lock);
|
||||
assert(r == 0);
|
||||
.Ed
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_sync
|
||||
function may be used with a serial queue to accomplish the same style of
|
||||
synchronization. For example:
|
||||
.Bd -literal -offset indent
|
||||
dispatch_sync(my_queue, ^{
|
||||
// critical section
|
||||
});
|
||||
.Ed
|
||||
.Pp
|
||||
In addition to providing a more concise expression of synchronization, this
|
||||
approach is less error prone as the critical section cannot be accidentally
|
||||
left without restoring the queue to a reentrant state.
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_async
|
||||
function may be used to implement deferred critical sections when the result
|
||||
of the block is not needed locally. Deferred critical sections have the same
|
||||
synchronization properties as the above code, but are non-blocking and
|
||||
therefore more efficient to perform. For example:
|
||||
.Bd -literal
|
||||
dispatch_async(my_queue, ^{
|
||||
// critical section
|
||||
});
|
||||
.Ed
|
||||
.Sh BACKGROUND CONCURRENCY
|
||||
.The
|
||||
.Fn dispatch_async
|
||||
function may be used to execute trivial background tasks on a global concurrent
|
||||
queue. For example:
|
||||
.Bd -literal
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
|
||||
// background operation
|
||||
});
|
||||
.Ed
|
||||
.Pp
|
||||
This approach is an efficient replacement for
|
||||
.Xr pthread_create 3 .
|
||||
.Sh COMPLETION CALLBACKS
|
||||
Completion callbacks can be accomplished via nested calls to the
|
||||
.Fn dispatch_async
|
||||
function. It is important to remember to retain the destination queue before the
|
||||
first call to
|
||||
.Fn dispatch_async ,
|
||||
and to release that queue at the end of the completion callback to ensure the
|
||||
destination queue is not deallocated while the completion callback is pending.
|
||||
For example:
|
||||
.Bd -literal
|
||||
void
|
||||
async_read(object_t obj,
|
||||
void *where, size_t bytes,
|
||||
dispatch_queue_t destination_queue,
|
||||
void (^reply_block)(ssize_t r, int err))
|
||||
{
|
||||
// There are better ways of doing async I/O.
|
||||
// This is just an example of nested blocks.
|
||||
|
||||
dispatch_retain(destination_queue);
|
||||
|
||||
dispatch_async(obj->queue, ^{
|
||||
ssize_t r = read(obj->fd, where, bytes);
|
||||
int err = errno;
|
||||
|
||||
dispatch_async(destination_queue, ^{
|
||||
reply_block(r, err);
|
||||
});
|
||||
dispatch_release(destination_queue);
|
||||
});
|
||||
}
|
||||
.Ed
|
||||
.Sh RECURSIVE LOCKS
|
||||
While
|
||||
.Fn dispatch_sync
|
||||
can replace a lock, it cannot replace a recursive lock. Unlike locks, queues
|
||||
support both asynchronous and synchronous operations, and those operations are
|
||||
ordered by definition. A recursive call to
|
||||
.Fn dispatch_sync
|
||||
causes a simple deadlock as the currently executing block waits for the next
|
||||
block to complete, but the next block will not start until the currently
|
||||
running block completes.
|
||||
.Pp
|
||||
As the dispatch framework was designed, we studied recursive locks. We found
|
||||
that the vast majority of recursive locks are deployed retroactively when
|
||||
ill-defined lock hierarchies are discovered. As a consequence, the adoption of
|
||||
recursive locks often mutates obvious bugs into obscure ones. This study also
|
||||
revealed an insight: if reentrancy is unavoidable, then reader/writer locks are
|
||||
preferable to recursive locks. Disciplined use of reader/writer locks enable
|
||||
reentrancy only when reentrancy is safe (the "read" side of the lock).
|
||||
.Pp
|
||||
Nevertheless, if it is absolutely necessary, what follows is an imperfect way of
|
||||
implementing recursive locks using the dispatch framework:
|
||||
.Bd -literal
|
||||
void
|
||||
sloppy_lock(object_t object, void (^block)(void))
|
||||
{
|
||||
if (object->owner == pthread_self()) {
|
||||
return block();
|
||||
}
|
||||
dispatch_sync(object->queue, ^{
|
||||
object->owner = pthread_self();
|
||||
block();
|
||||
object->owner = NULL;
|
||||
});
|
||||
}
|
||||
.Ed
|
||||
.Pp
|
||||
The above example does not solve the case where queue A runs on thread X which
|
||||
calls
|
||||
.Fn dispatch_sync
|
||||
against queue B which runs on thread Y which recursively calls
|
||||
.Fn dispatch_sync
|
||||
against queue A, which deadlocks both examples. This is bug-for-bug compatible
|
||||
with nontrivial pthread usage. In fact, nontrivial reentrancy is impossible to
|
||||
support in recursive locks once the ultimate level of reentrancy is deployed
|
||||
(IPC or RPC).
|
||||
.Sh IMPLIED REFERENCES
|
||||
Synchronous functions within the dispatch framework hold an implied reference
|
||||
on the target queue. In other words, the synchronous function borrows the
|
||||
reference of the calling function (this is valid because the calling function
|
||||
is blocked waiting for the result of the synchronous function, and therefore
|
||||
cannot modify the reference count of the target queue until after the
|
||||
synchronous function has returned).
|
||||
For example:
|
||||
.Bd -literal
|
||||
queue = dispatch_queue_create("com.example.queue", NULL);
|
||||
assert(queue);
|
||||
dispatch_sync(queue, ^{
|
||||
do_something();
|
||||
//dispatch_release(queue); // NOT SAFE -- dispatch_sync() is still using 'queue'
|
||||
});
|
||||
dispatch_release(queue); // SAFELY balanced outside of the block provided to dispatch_sync()
|
||||
.Ed
|
||||
.Pp
|
||||
This is in contrast to asynchronous functions which must retain both the block
|
||||
and target queue for the duration of the asynchronous operation (as the calling
|
||||
function may immediately release its interest in these objects).
|
||||
.Sh FUNDAMENTALS
|
||||
Conceptually,
|
||||
.Fn dispatch_sync
|
||||
is a convenient wrapper around
|
||||
.Fn dispatch_async
|
||||
with the addition of a semaphore to wait for completion of the block, and a
|
||||
wrapper around the block to signal its completion. See
|
||||
.Xr dispatch_semaphore_create 3
|
||||
for more information about dispatch semaphores. The actual implementation of the
|
||||
.Fn dispatch_sync
|
||||
function may be optimized and differ from the above description.
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_async
|
||||
function is a wrapper around
|
||||
.Fn dispatch_async_f .
|
||||
The application-defined
|
||||
.Fa context
|
||||
parameter is passed to the
|
||||
.Fa function
|
||||
when it is invoked on the target
|
||||
.Fa queue .
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_sync
|
||||
function is a wrapper around
|
||||
.Fn dispatch_sync_f .
|
||||
The application-defined
|
||||
.Fa context
|
||||
parameter is passed to the
|
||||
.Fa function
|
||||
when it is invoked on the target
|
||||
.Fa queue .
|
||||
.Pp
|
||||
.Sh SEE ALSO
|
||||
.Xr dispatch 3 ,
|
||||
.Xr dispatch_apply 3 ,
|
||||
.Xr dispatch_once 3 ,
|
||||
.Xr dispatch_queue_create 3 ,
|
||||
.Xr dispatch_semaphore_create 3
|
||||
59
Telegram/ThirdParty/dispatch/man/dispatch_benchmark.3
vendored
Normal file
59
Telegram/ThirdParty/dispatch/man/dispatch_benchmark.3
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
.\" Copyright (c) 2008-2009 Apple Inc. All rights reserved.
|
||||
.Dd May 1, 2009
|
||||
.Dt dispatch_benchmark 3
|
||||
.Os Darwin
|
||||
.Sh NAME
|
||||
.Nm dispatch_benchmark
|
||||
.Nd Measures block execution time
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <dispatch/dispatch.h>
|
||||
.Ft uint64_t
|
||||
.Fo dispatch_benchmark
|
||||
.Fa "size_t count" "void (^block)(void)"
|
||||
.Fc
|
||||
.Ft uint64_t
|
||||
.Fo dispatch_benchmark_f
|
||||
.Fa "size_t count" "void *context" "void (*function)(void *)"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn dispatch_benchmark
|
||||
function executes the given
|
||||
.Fa block
|
||||
multiple times according to the
|
||||
.Fa count
|
||||
variable and then returns the average number of nanoseconds per execution.
|
||||
This function is for debugging and performance analysis work.
|
||||
For the best
|
||||
results, pass a high count value to
|
||||
.Fn dispatch_benchmark .
|
||||
When benchmarking concurrent code, please compare the
|
||||
serial version of the code against the concurrent version, and compare the
|
||||
concurrent version on different classes of hardware.
|
||||
Please look for inflection
|
||||
points with various data sets and keep the following facts in mind:
|
||||
.Pp
|
||||
.Bl -bullet -offset indent -compact
|
||||
.It
|
||||
Code bound by computational bandwidth may be inferred by proportional
|
||||
changes in performance as concurrency is increased.
|
||||
.It
|
||||
Code bound by memory bandwidth may be inferred by negligible changes in
|
||||
performance as concurrency is increased.
|
||||
.It
|
||||
Code bound by critical sections may be inferred by retrograde changes in
|
||||
performance as concurrency is increased.
|
||||
.Bl -bullet -offset indent -compact
|
||||
.It
|
||||
Intentional: locks, mutexes, and condition variables.
|
||||
.It
|
||||
Accidental: unrelated and frequently modified data on the same cache-line.
|
||||
.El
|
||||
.El
|
||||
.Sh RETURN VALUE
|
||||
The
|
||||
.Fn dispatch_benchmark
|
||||
function returns the average number of nanoseconds the given block takes to
|
||||
execute.
|
||||
.Sh SEE ALSO
|
||||
.Xr dispatch 3
|
||||
220
Telegram/ThirdParty/dispatch/man/dispatch_data_create.3
vendored
Normal file
220
Telegram/ThirdParty/dispatch/man/dispatch_data_create.3
vendored
Normal file
@@ -0,0 +1,220 @@
|
||||
.\" Copyright (c) 2010-2012 Apple Inc. All rights reserved.
|
||||
.Dd December 1, 2010
|
||||
.Dt dispatch_data_create 3
|
||||
.Os Darwin
|
||||
.Sh NAME
|
||||
.Nm dispatch_data_create ,
|
||||
.Nm dispatch_data_create_concat ,
|
||||
.Nm dispatch_data_create_subrange ,
|
||||
.Nm dispatch_data_create_map ,
|
||||
.Nm dispatch_data_apply ,
|
||||
.Nm dispatch_data_copy_region ,
|
||||
.Nm dispatch_data_get_size
|
||||
.Nd create and manipulate dispatch data objects
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <dispatch/dispatch.h>
|
||||
.Ft dispatch_data_t
|
||||
.Fo dispatch_data_create
|
||||
.Fa "const void* buffer"
|
||||
.Fa "size_t size"
|
||||
.Fa "dispatch_queue_t queue"
|
||||
.Fa "dispatch_block_t destructor"
|
||||
.Fc
|
||||
.Ft dispatch_data_t
|
||||
.Fo dispatch_data_create_concat
|
||||
.Fa "dispatch_data_t data1"
|
||||
.Fa "dispatch_data_t data2"
|
||||
.Fc
|
||||
.Ft dispatch_data_t
|
||||
.Fo dispatch_data_create_subrange
|
||||
.Fa "dispatch_data_t data"
|
||||
.Fa "size_t offset"
|
||||
.Fa "size_t length"
|
||||
.Fc
|
||||
.Ft dispatch_data_t
|
||||
.Fo dispatch_data_create_map
|
||||
.Fa "dispatch_data_t data"
|
||||
.Fa "const void **buffer_ptr"
|
||||
.Fa "size_t *size_ptr"
|
||||
.Fc
|
||||
.Ft bool
|
||||
.Fo dispatch_data_apply
|
||||
.Fa "dispatch_data_t data"
|
||||
.Fa "bool (^applier)(dispatch_data_t, size_t, const void *, size_t)"
|
||||
.Fc
|
||||
.Ft dispatch_data_t
|
||||
.Fo dispatch_data_copy_region
|
||||
.Fa "dispatch_data_t data"
|
||||
.Fa "size_t location"
|
||||
.Fa "size_t *offset_ptr"
|
||||
.Fc
|
||||
.Ft size_t
|
||||
.Fo dispatch_data_get_size
|
||||
.Fa "dispatch_data_t data"
|
||||
.Fc
|
||||
.Vt dispatch_data_t dispatch_data_empty ;
|
||||
.Sh DESCRIPTION
|
||||
Dispatch data objects are opaque containers of bytes that represent one or more
|
||||
regions of memory. They are created either from memory buffers managed by the
|
||||
application or the system or from other dispatch data objects. Dispatch data
|
||||
objects are immutable and the memory regions they represent are required to
|
||||
remain unchanged for the lifetime of all data objects that reference them.
|
||||
Dispatch data objects avoid copying the represented memory as much as possible.
|
||||
Multiple data objects can represent the same memory regions or subsections
|
||||
thereof.
|
||||
.Sh CREATION
|
||||
The
|
||||
.Fn dispatch_data_create
|
||||
function creates a new dispatch data object of given
|
||||
.Fa size
|
||||
from a
|
||||
.Fa buffer .
|
||||
The provided
|
||||
.Fa destructor
|
||||
block will be submitted to the specified
|
||||
.Fa queue
|
||||
when the object reaches the end of its lifecycle, indicating that the system no
|
||||
longer references the
|
||||
.Fa buffer .
|
||||
This allows the application to deallocate
|
||||
the associated storage. The
|
||||
.Fa queue
|
||||
argument is ignored if one of the following predefined destructors is passed:
|
||||
.Bl -tag -width DISPATCH_DATA_DESTRUCTOR_DEFAULT -compact -offset indent
|
||||
.It DISPATCH_DATA_DESTRUCTOR_FREE
|
||||
indicates that the provided buffer can be deallocated with
|
||||
.Xr free 3
|
||||
directly.
|
||||
.It DISPATCH_DATA_DESTRUCTOR_DEFAULT
|
||||
indicates that the provided buffer is not managed by the application and should
|
||||
be copied into memory managed and automatically deallocated by the system.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_data_create_concat
|
||||
function creates a new data object representing the concatenation of the memory
|
||||
regions represented by the provided data objects.
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_data_create_subrange
|
||||
function creates a new data object representing the sub-region of the provided
|
||||
.Fa data
|
||||
object specified by the
|
||||
.Fa offset
|
||||
and
|
||||
.Fa length
|
||||
parameters.
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_data_create_map
|
||||
function creates a new data object by mapping the memory represented by the
|
||||
provided
|
||||
.Fa data
|
||||
object as a single contiguous memory region (moving or copying memory as
|
||||
necessary). If the
|
||||
.Fa buffer_ptr
|
||||
and
|
||||
.Fa size_ptr
|
||||
references are not
|
||||
.Dv NULL ,
|
||||
they are filled with the location and extent of the contiguous region, allowing
|
||||
direct read access to the mapped memory. These values are valid only as long as
|
||||
the newly created object has not been released.
|
||||
.Sh ACCESS
|
||||
The
|
||||
.Fn dispatch_data_apply
|
||||
function provides read access to represented memory without requiring it to be
|
||||
mapped as a single contiguous region. It traverses the memory regions
|
||||
represented by the
|
||||
.Fa data
|
||||
argument in logical order, invokes the specified
|
||||
.Fa applier
|
||||
block for each region and returns a boolean indicating whether traversal
|
||||
completed successfully. The
|
||||
.Fa applier
|
||||
block is passed the following arguments for each memory region and returns a
|
||||
boolean indicating whether traversal should continue:
|
||||
.Bl -tag -width "dispatch_data_t rgn" -compact -offset indent
|
||||
.It Fa "dispatch_data_t rgn"
|
||||
data object representing the region
|
||||
.It Fa "size_t offset"
|
||||
logical position of the region in
|
||||
.Fa data
|
||||
.It Vt "const void *loc"
|
||||
memory location of the region
|
||||
.It Vt "size_t size"
|
||||
extent of the region
|
||||
.El
|
||||
The
|
||||
.Fa rgn
|
||||
data object is released by the system when the
|
||||
.Fa applier
|
||||
block returns.
|
||||
The associated memory location
|
||||
.Fa loc
|
||||
is valid only as long as
|
||||
.Fa rgn
|
||||
has not been deallocated; if
|
||||
.Fa loc
|
||||
is needed outside of the
|
||||
.Fa applier
|
||||
block, the
|
||||
.Fa rgn
|
||||
object must be retained in the block.
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_data_copy_region
|
||||
function finds the contiguous memory region containing the logical position
|
||||
specified by the
|
||||
.Fa location
|
||||
argument among the regions represented by the provided
|
||||
.Fa data
|
||||
object and returns a newly created copy of the data object representing that
|
||||
region. The variable specified by the
|
||||
.Fa offset_ptr
|
||||
argument is filled with the logical position where the returned object starts
|
||||
in the
|
||||
.Fa data
|
||||
object.
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_data_get_size
|
||||
function returns the logical size of the memory region or regions represented
|
||||
by the provided
|
||||
.Fa data
|
||||
object.
|
||||
.Sh EMPTY DATA OBJECT
|
||||
The
|
||||
.Vt dispatch_data_empty
|
||||
object is the global singleton object representing a zero-length memory region.
|
||||
It is a valid input to any dispatch_data functions that take data object
|
||||
parameters.
|
||||
.Sh MEMORY MODEL
|
||||
Dispatch data objects are retained and released via calls to
|
||||
.Fn dispatch_retain
|
||||
and
|
||||
.Fn dispatch_release .
|
||||
Data objects passed as arguments to a dispatch data
|
||||
.Sy create
|
||||
or
|
||||
.Sy copy
|
||||
function can be released when the function returns. The newly created object
|
||||
holds implicit references to their constituent memory regions as necessary.
|
||||
.Pp
|
||||
The functions
|
||||
.Fn dispatch_data_create_map
|
||||
and
|
||||
.Fn dispatch_data_apply
|
||||
return an interior pointer to represented memory that is only valid as long as
|
||||
an associated object has not been released. When Objective-C Automated
|
||||
Reference Counting is enabled, care needs to be taken if that object is held in
|
||||
a variable with automatic storage. It may need to be annotated with the
|
||||
.Li objc_precise_lifetime
|
||||
attribute, or stored in a
|
||||
.Li __strong
|
||||
instance variable instead, to ensure that the object is not released
|
||||
prematurely before memory accesses via the interor pointer have been completed.
|
||||
.Sh SEE ALSO
|
||||
.Xr dispatch 3 ,
|
||||
.Xr dispatch_object 3 ,
|
||||
.Xr dispatch_io_read 3
|
||||
180
Telegram/ThirdParty/dispatch/man/dispatch_group_create.3
vendored
Normal file
180
Telegram/ThirdParty/dispatch/man/dispatch_group_create.3
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
.\" Copyright (c) 2008-2012 Apple Inc. All rights reserved.
|
||||
.Dd May 1, 2009
|
||||
.Dt dispatch_group_create 3
|
||||
.Os Darwin
|
||||
.Sh NAME
|
||||
.Nm dispatch_group_create ,
|
||||
.Nm dispatch_group_async ,
|
||||
.Nm dispatch_group_wait ,
|
||||
.Nm dispatch_group_notify
|
||||
.Nd group blocks submitted to queues
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <dispatch/dispatch.h>
|
||||
.Ft dispatch_group_t
|
||||
.Fo dispatch_group_create
|
||||
.Fa void
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_group_enter
|
||||
.Fa "dispatch_group_t group"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_group_leave
|
||||
.Fa "dispatch_group_t group"
|
||||
.Fc
|
||||
.Ft long
|
||||
.Fo dispatch_group_wait
|
||||
.Fa "dispatch_group_t group" "dispatch_time_t timeout"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_group_notify
|
||||
.Fa "dispatch_group_t group" "dispatch_queue_t queue" "void (^block)(void)"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_group_notify_f
|
||||
.Fa "dispatch_group_t group" "dispatch_queue_t queue" "void *context" "void (*function)(void *)"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_group_async
|
||||
.Fa "dispatch_group_t group" "dispatch_queue_t queue" "void (^block)(void)"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_group_async_f
|
||||
.Fa "dispatch_group_t group" "dispatch_queue_t queue" "void *context" "void (*function)(void *)"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
A dispatch group is an association of one or more blocks submitted to dispatch
|
||||
queues for asynchronous invocation.
|
||||
Applications may use dispatch groups to
|
||||
wait for the completion of blocks associated with the group.
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_group_create
|
||||
function returns a new and empty dispatch group.
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_group_enter
|
||||
and
|
||||
.Fn dispatch_group_leave
|
||||
functions update the number of blocks running within a group.
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_group_wait
|
||||
function waits until all blocks associated with the
|
||||
.Fa group
|
||||
have completed, or until the specified
|
||||
.Fa timeout
|
||||
has elapsed.
|
||||
If the
|
||||
.Fa group
|
||||
becomes empty within the specified amount of time, the function will return zero
|
||||
indicating success. Otherwise, a non-zero return code will be returned.
|
||||
When
|
||||
.Va DISPATCH_TIME_FOREVER
|
||||
is passed as the
|
||||
.Fa timeout ,
|
||||
calls to this function will wait an unlimited amount of time until the group
|
||||
becomes empty and the return value is always zero.
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_group_notify
|
||||
function provides asynchronous notification of the completion of the blocks
|
||||
associated with the
|
||||
.Fa group
|
||||
by submitting the
|
||||
.Fa block
|
||||
to the specified
|
||||
.Fa queue
|
||||
once all blocks associated with the
|
||||
.Fa group
|
||||
have completed.
|
||||
The system holds a reference to the dispatch group while an asynchronous
|
||||
notification is pending, therefore it is valid to release the
|
||||
.Fa group
|
||||
after setting a notification block.
|
||||
The group will be empty at the time the notification block is submitted to the
|
||||
target queue. The group may either be released with
|
||||
.Fn dispatch_release
|
||||
or reused for additional operations.
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_group_async
|
||||
convenience function behaves like so:
|
||||
.Bd -literal
|
||||
void
|
||||
dispatch_group_async(dispatch_group_t group, dispatch_queue_t queue, dispatch_block_t block)
|
||||
{
|
||||
dispatch_retain(group);
|
||||
dispatch_group_enter(group);
|
||||
dispatch_async(queue, ^{
|
||||
block();
|
||||
dispatch_group_leave(group);
|
||||
dispatch_release(group);
|
||||
});
|
||||
}
|
||||
.Ed
|
||||
.Sh RETURN VALUE
|
||||
The
|
||||
.Fn dispatch_group_create
|
||||
function returns NULL on failure and non-NULL on success.
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_group_wait
|
||||
function returns zero upon success and non-zero after the timeout expires.
|
||||
If the timeout is
|
||||
.Va DISPATCH_TIME_FOREVER ,
|
||||
then
|
||||
.Fn dispatch_group_wait
|
||||
waits forever and always returns zero.
|
||||
.Sh MEMORY MODEL
|
||||
Dispatch groups are retained and released via calls to
|
||||
.Fn dispatch_retain
|
||||
and
|
||||
.Fn dispatch_release .
|
||||
.Sh FUNDAMENTALS
|
||||
The
|
||||
.Fn dispatch_group_async
|
||||
and
|
||||
.Fn dispatch_group_notify
|
||||
functions are wrappers around
|
||||
.Fn dispatch_group_async_f
|
||||
and
|
||||
.Fn dispatch_group_notify_f
|
||||
respectively.
|
||||
.Sh CAVEATS
|
||||
In order to ensure deterministic behavior, it is recommended to call
|
||||
.Fn dispatch_group_wait
|
||||
only once all blocks have been submitted to the group. If it is later
|
||||
determined that new blocks should be run, it is recommended not to reuse an
|
||||
already-running group, but to create a new group.
|
||||
.Pp
|
||||
.Fn dispatch_group_wait
|
||||
returns as soon as there are exactly zero
|
||||
.Em enqueued or running
|
||||
blocks associated with a group (more precisely, as soon as every
|
||||
.Fn dispatch_group_enter
|
||||
call has been balanced by a
|
||||
.Fn dispatch_group_leave
|
||||
call). If one thread waits for a group while another thread submits
|
||||
new blocks to the group, then the count of associated blocks might
|
||||
momentarily reach zero before all blocks have been submitted. If this happens,
|
||||
.Fn dispatch_group_wait
|
||||
will return too early: some blocks associated with the group have finished,
|
||||
but some have not yet been submitted or run.
|
||||
.Pp
|
||||
However, as a special case, a block associated with a group may submit new
|
||||
blocks associated with its own group. In this case, the behavior is
|
||||
deterministic: a waiting thread will
|
||||
.Em not
|
||||
wake up until the newly submitted blocks have also finished.
|
||||
.Pp
|
||||
All of the foregoing also applies to
|
||||
.Fn dispath_group_notify
|
||||
as well, with "block to be submitted" substituted for "waiting thread".
|
||||
.Sh SEE ALSO
|
||||
.Xr dispatch 3 ,
|
||||
.Xr dispatch_async 3 ,
|
||||
.Xr dispatch_object 3 ,
|
||||
.Xr dispatch_queue_create 3 ,
|
||||
.Xr dispatch_semaphore_create 3 ,
|
||||
.Xr dispatch_time 3
|
||||
282
Telegram/ThirdParty/dispatch/man/dispatch_io_create.3
vendored
Normal file
282
Telegram/ThirdParty/dispatch/man/dispatch_io_create.3
vendored
Normal file
@@ -0,0 +1,282 @@
|
||||
.\" Copyright (c) 2010-2013 Apple Inc. All rights reserved.
|
||||
.Dd December 1, 2010
|
||||
.Dt dispatch_io_create 3
|
||||
.Os Darwin
|
||||
.Sh NAME
|
||||
.Nm dispatch_io_create ,
|
||||
.Nm dispatch_io_create_with_path ,
|
||||
.Nm dispatch_io_close ,
|
||||
.Nm dispatch_io_set_high_water ,
|
||||
.Nm dispatch_io_set_low_water ,
|
||||
.Nm dispatch_io_set_interval ,
|
||||
.Nm dispatch_io_barrier
|
||||
.Nd open, close and configure dispatch I/O channels
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <dispatch/dispatch.h>
|
||||
.Ft dispatch_io_t
|
||||
.Fo dispatch_io_create
|
||||
.Fa "dispatch_io_type_t type"
|
||||
.Fa "int fd"
|
||||
.Fa "dispatch_queue_t queue"
|
||||
.Fa "void (^cleanup_handler)(int error)"
|
||||
.Fc
|
||||
.Ft dispatch_io_t
|
||||
.Fo dispatch_io_create_with_path
|
||||
.Fa "dispatch_io_type_t type"
|
||||
.Fa "const char *path"
|
||||
.Fa "int oflag"
|
||||
.Fa "mode_t mode"
|
||||
.Fa "dispatch_queue_t queue"
|
||||
.Fa "void (^cleanup_handler)(int error)"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_io_close
|
||||
.Fa "dispatch_io_t channel"
|
||||
.Fa "dispatch_io_close_flags_t flags"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_io_set_high_water
|
||||
.Fa "dispatch_io_t channel"
|
||||
.Fa "size_t high_water"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_io_set_low_water
|
||||
.Fa "dispatch_io_t channel"
|
||||
.Fa "size_t low_water"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_io_set_interval
|
||||
.Fa "dispatch_io_t channel"
|
||||
.Fa "uint64_t interval"
|
||||
.Fa "dispatch_io_interval_flags_t flags"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_io_barrier
|
||||
.Fa "dispatch_io_t channel"
|
||||
.Fa "void (^barrier)(void)"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
The dispatch I/O framework is an API for asynchronous read and write I/O
|
||||
operations. It is an application of the ideas and idioms present in the
|
||||
.Xr dispatch 3
|
||||
framework to device I/O. Dispatch I/O enables an application to more easily
|
||||
avoid blocking I/O operations and allows it to more directly express its I/O
|
||||
requirements than by using the raw POSIX file API. Dispatch I/O will make a
|
||||
best effort to optimize how and when asynchronous I/O operations are performed
|
||||
based on the capabilities of the targeted device.
|
||||
.Pp
|
||||
This page provides details on how to create and configure dispatch I/O
|
||||
channels. Reading from and writing to these channels is covered in the
|
||||
.Xr dispatch_io_read 3
|
||||
page. The dispatch I/O framework also provides the convenience functions
|
||||
.Xr dispatch_read 3
|
||||
and
|
||||
.Xr dispatch_write 3
|
||||
for uses that do not require the full functionality provided by I/O channels.
|
||||
.Sh FUNDAMENTALS
|
||||
A dispatch I/O channel represents the asynchronous I/O policy applied to a file
|
||||
descriptor and encapsulates it for the purposes of ownership tracking while
|
||||
I/O operations are ongoing.
|
||||
.Sh CHANNEL TYPES
|
||||
Dispatch I/O channels can have one of the following types:
|
||||
.Bl -tag -width DISPATCH_IO_STREAM -compact -offset indent
|
||||
.It DISPATCH_IO_STREAM
|
||||
channels that represent a stream of bytes and do not support reads and writes
|
||||
at arbitrary offsets, such as pipes or sockets. Channels of this type perform
|
||||
read and write operations sequentially at the current file pointer position and
|
||||
ignore any offset specified. Depending on the underlying file descriptor, read
|
||||
operations may be performed simultaneously with write operations.
|
||||
.It DISPATCH_IO_RANDOM
|
||||
channels that represent random access files on disk. Only supported for
|
||||
seekable file descriptors and paths. Channels of this type may perform
|
||||
submitted read and write operations concurrently at the specified offset
|
||||
(interpreted relative to the position of the file pointer when the channel was
|
||||
created).
|
||||
.El
|
||||
.Sh CHANNEL OPENING AND CLOSING
|
||||
The
|
||||
.Fn dispatch_io_create
|
||||
and
|
||||
.Fn dispatch_io_create_with_path
|
||||
functions create a dispatch I/O channel of provided
|
||||
.Fa type
|
||||
from a file descriptor
|
||||
.Fa fd
|
||||
or an absolute pathname, respectively. They can be thought of as analogous to
|
||||
the
|
||||
.Xr fdopen 3
|
||||
POSIX function and the
|
||||
.Xr fopen 3
|
||||
function in the standard C library. For a channel created from a pathname, the
|
||||
provided
|
||||
.Fa path ,
|
||||
.Fa oflag
|
||||
and
|
||||
.Fa mode
|
||||
parameters will be passed to
|
||||
.Xr open 2
|
||||
when the first I/O operation on the channel is ready to execute.
|
||||
.Pp
|
||||
The provided
|
||||
.Fa cleanup_handler
|
||||
block will be submitted to the specified
|
||||
.Fa queue
|
||||
when all I/O operations on the channel have completed and it is closed or
|
||||
reaches the end of its lifecycle. If an error occurs during channel creation,
|
||||
the
|
||||
.Fa cleanup_handler
|
||||
block will be submitted immediately and passed an
|
||||
.Fa error
|
||||
parameter with the POSIX error encountered. If an invalid
|
||||
.Fa type
|
||||
or a non-absolute
|
||||
.Fa path
|
||||
argument is specified, these functions will return NULL and the
|
||||
.Fa cleanup_handler
|
||||
will not be invoked. After successfully creating a dispatch I/O channel from a
|
||||
file descriptor, the application must take care not to modify that file
|
||||
descriptor until the associated
|
||||
.Fa cleanup_handler
|
||||
is invoked, see
|
||||
.Sx "FILEDESCRIPTOR OWNERSHIP"
|
||||
for details.
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_io_close
|
||||
function closes a dispatch I/O channel to new submissions of I/O operations. If
|
||||
.Dv DISPATCH_IO_STOP
|
||||
is passed in the
|
||||
.Fa flags
|
||||
parameter, the system will in addition not perform the I/O operations already
|
||||
submitted to the channel that are still pending and will make a best effort to
|
||||
interrupt any ongoing operations. Handlers for operations so affected will be
|
||||
passed the
|
||||
.Er ECANCELED
|
||||
error code, along with any partial results.
|
||||
.Sh CHANNEL CONFIGURATION
|
||||
Dispatch I/O channels have high-water mark, low-water mark and interval
|
||||
configuration settings that determine if and when partial results from I/O
|
||||
operations are delivered via their associated I/O handlers.
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_io_set_high_water
|
||||
and
|
||||
.Fn dispatch_io_set_low_water
|
||||
functions configure the water mark settings of a
|
||||
.Fa channel .
|
||||
The system will read
|
||||
or write at least the number of bytes specified by
|
||||
.Fa low_water
|
||||
before submitting an I/O handler with partial results, and will make a best
|
||||
effort to submit an I/O handler as soon as the number of bytes read or written
|
||||
reaches
|
||||
.Fa high_water .
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_io_set_interval
|
||||
function configures the time
|
||||
.Fa interval
|
||||
at which I/O handlers are submitted (measured in nanoseconds). If
|
||||
.Dv DISPATCH_IO_STRICT_INTERVAL
|
||||
is passed in the
|
||||
.Fa flags
|
||||
parameter, the interval will be strictly observed even if there is an
|
||||
insufficient amount of data to deliver; otherwise delivery will be skipped for
|
||||
intervals where the amount of available data is inferior to the channel's
|
||||
low-water mark. Note that the system may defer enqueueing interval I/O handlers
|
||||
by a small unspecified amount of leeway in order to align with other system
|
||||
activity for improved system performance or power consumption.
|
||||
.Pp
|
||||
.Sh DATA DELIVERY
|
||||
The size of data objects passed to I/O handlers for a channel will never be
|
||||
larger than the high-water mark set on the channel; it will also never be
|
||||
smaller than the low-water mark, except in the following cases:
|
||||
.Bl -dash -offset indent -compact
|
||||
.It
|
||||
the final handler invocation for an I/O operation
|
||||
.It
|
||||
EOF was encountered
|
||||
.It
|
||||
the channel has an interval with the
|
||||
.Dv DISPATCH_IO_STRICT_INTERVAL
|
||||
flag set
|
||||
.El
|
||||
Bear in mind that dispatch I/O channels will typically deliver amounts of data
|
||||
significantly higher than the low-water mark. The default value for the
|
||||
low-water mark is unspecified, but must be assumed to allow intermediate
|
||||
handler invocations. The default value for the high-water mark is
|
||||
unlimited (i.e.\&
|
||||
.Dv SIZE_MAX ) .
|
||||
Channels that require intermediate results of fixed size should have both the
|
||||
low-water and the high-water mark set to that size. Channels that do not wish
|
||||
to receive any intermediate results should have the low-water mark set to
|
||||
.Dv SIZE_MAX .
|
||||
.Pp
|
||||
.Sh FILEDESCRIPTOR OWNERSHIP
|
||||
When an application creates a dispatch I/O channel from a file descriptor with
|
||||
the
|
||||
.Fn dispatch_io_create
|
||||
function, the system takes control of that file descriptor until the channel is
|
||||
closed, an error occurs on the file descriptor or all references to the channel
|
||||
are released. At that time the channel's cleanup handler will be enqueued and
|
||||
control over the file descriptor relinquished, making it safe for the
|
||||
application to
|
||||
.Xr close 2
|
||||
the file descriptor. While a file descriptor is under the control of a dispatch
|
||||
I/O channel, file descriptor flags such as
|
||||
.Dv O_NONBLOCK
|
||||
will be modified by the system on behalf of the application. It is an error for
|
||||
the application to modify a file descriptor directly while it is under the
|
||||
control of a dispatch I/O channel, but it may create further I/O channels
|
||||
from that file descriptor or use the
|
||||
.Xr dispatch_read 3
|
||||
and
|
||||
.Xr dispatch_write 3
|
||||
convenience functions with that file descriptor. If multiple I/O channels have
|
||||
been created from the same file descriptor, all the associated cleanup handlers
|
||||
will be submitted together once the last channel has been closed resp.\& all
|
||||
references to those channels have been released. If convenience functions have
|
||||
also been used on that file descriptor, submission of their handlers will be
|
||||
tied to the submission of the channel cleanup handlers as well.
|
||||
.Pp
|
||||
.Sh BARRIER OPERATIONS
|
||||
The
|
||||
.Fn dispatch_io_barrier
|
||||
function schedules a barrier operation on an I/O channel. The specified barrier
|
||||
block will be run once, after all current I/O operations (such as
|
||||
.Xr read 2 or
|
||||
.Xr write 2 )
|
||||
on the underlying
|
||||
file descriptor have finished. No new I/O operations will start until the
|
||||
barrier block finishes.
|
||||
.Pp
|
||||
The barrier block may operate on the underlying file descriptor with functions
|
||||
like
|
||||
.Xr fsync 2
|
||||
or
|
||||
.Xr lseek 2 .
|
||||
As discussed in the
|
||||
.Sx FILEDESCRIPTOR OWNERSHIP
|
||||
section, the barrier block must not
|
||||
.Xr close 2
|
||||
the file descriptor, and if it changes any flags on the file descriptor, it
|
||||
must restore them before finishing.
|
||||
.Pp
|
||||
There is no synchronization between a barrier block and any
|
||||
.Xr dispatch_io_read 3
|
||||
or
|
||||
.Xr dispatch_io_write 3
|
||||
handler blocks; they may be running at the same time. The barrier block itself
|
||||
is responsible for any required synchronization.
|
||||
.Sh MEMORY MODEL
|
||||
Dispatch I/O channel objects are retained and released via calls to
|
||||
.Fn dispatch_retain
|
||||
and
|
||||
.Fn dispatch_release .
|
||||
.Sh SEE ALSO
|
||||
.Xr dispatch 3 ,
|
||||
.Xr dispatch_io_read 3 ,
|
||||
.Xr dispatch_object 3 ,
|
||||
.Xr dispatch_read 3 ,
|
||||
.Xr fopen 3 ,
|
||||
.Xr open 2
|
||||
151
Telegram/ThirdParty/dispatch/man/dispatch_io_read.3
vendored
Normal file
151
Telegram/ThirdParty/dispatch/man/dispatch_io_read.3
vendored
Normal file
@@ -0,0 +1,151 @@
|
||||
.\" Copyright (c) 2010 Apple Inc. All rights reserved.
|
||||
.Dd December 1, 2010
|
||||
.Dt dispatch_io_read 3
|
||||
.Os Darwin
|
||||
.Sh NAME
|
||||
.Nm dispatch_io_read ,
|
||||
.Nm dispatch_io_write
|
||||
.Nd submit read and write operations to dispatch I/O channels
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <dispatch/dispatch.h>
|
||||
.Ft void
|
||||
.Fo dispatch_io_read
|
||||
.Fa "dispatch_io_t channel"
|
||||
.Fa "off_t offset"
|
||||
.Fa "size_t length"
|
||||
.Fa "dispatch_queue_t queue"
|
||||
.Fa "void (^handler)(bool done, dispatch_data_t data, int error)"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_io_write
|
||||
.Fa "dispatch_io_t channel"
|
||||
.Fa "off_t offset"
|
||||
.Fa "dispatch_data_t data"
|
||||
.Fa "dispatch_queue_t queue"
|
||||
.Fa "void (^handler)(bool done, dispatch_data_t data, int error)"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
The dispatch I/O framework is an API for asynchronous read and write I/O
|
||||
operations. It is an application of the ideas and idioms present in the
|
||||
.Xr dispatch 3
|
||||
framework to device I/O. Dispatch I/O enables an application to more easily
|
||||
avoid blocking I/O operations and allows it to more directly express its I/O
|
||||
requirements than by using the raw POSIX file API. Dispatch I/O will make a
|
||||
best effort to optimize how and when asynchronous I/O operations are performed
|
||||
based on the capabilities of the targeted device.
|
||||
.Pp
|
||||
This page provides details on how to read from and write to dispatch I/O
|
||||
channels. Creation and configuration of these channels is covered in the
|
||||
.Xr dispatch_io_create 3
|
||||
page. The dispatch I/O framework also provides the convenience functions
|
||||
.Xr dispatch_read 3
|
||||
and
|
||||
.Xr dispatch_write 3
|
||||
for uses that do not require the full functionality provided by I/O channels.
|
||||
.Pp
|
||||
.Sh FUNDAMENTALS
|
||||
The
|
||||
.Fn dispatch_io_read
|
||||
and
|
||||
.Fn dispatch_io_write
|
||||
functions are used to perform asynchronous read and write operations on
|
||||
dispatch I/O channels. They can be thought of as asynchronous versions of the
|
||||
.Xr fread 3
|
||||
and
|
||||
.Xr fwrite 3
|
||||
functions in the standard C library.
|
||||
.Sh READ OPERATIONS
|
||||
The
|
||||
.Fn dispatch_io_read
|
||||
function schedules an I/O read operation on the specified dispatch I/O
|
||||
.Va channel .
|
||||
As results from the read operation become available, the provided
|
||||
.Va handler
|
||||
block will be submitted to the specified
|
||||
.Va queue .
|
||||
The block will be passed a dispatch data object representing the data that has
|
||||
been read since the handler's previous invocation.
|
||||
.Pp
|
||||
The
|
||||
.Va offset
|
||||
parameter indicates where the read operation should begin. For a channel of
|
||||
.Dv DISPATCH_IO_RANDOM
|
||||
type it is interpreted relative to the position of the file pointer when the
|
||||
channel was created, for a channel of
|
||||
.Dv DISPATCH_IO_STREAM
|
||||
type it is ignored and the read operation will begin at the current file
|
||||
pointer position.
|
||||
.Pp
|
||||
The
|
||||
.Va length
|
||||
parameter indicates the number of bytes that should be read from the I/O
|
||||
channel. Pass
|
||||
.Dv SIZE_MAX
|
||||
to keep reading until EOF is encountered (for a channel created from a
|
||||
disk-based file this happens when reading past the end of the physical file).
|
||||
.Sh WRITE OPERATIONS
|
||||
The
|
||||
.Fn dispatch_io_write
|
||||
function schedules an I/O write operation on the specified dispatch I/O
|
||||
.Va channel .
|
||||
As the write operation progresses, the provided
|
||||
.Va handler
|
||||
block will be submitted to the specified
|
||||
.Va queue .
|
||||
The block will be passed a dispatch data object representing the data that
|
||||
remains to be written as part of this I/O operation.
|
||||
.Pp
|
||||
The
|
||||
.Va offset
|
||||
parameter indicates where the write operation should begin. It is interpreted
|
||||
as for read operations above.
|
||||
.Pp
|
||||
The
|
||||
.Va data
|
||||
parameter specifies the location and amount of data to be written, encapsulated
|
||||
as a dispatch data object. The object is retained by the system until the write
|
||||
operation is complete.
|
||||
.Sh I/O HANDLER BLOCKS
|
||||
Dispatch I/O handler blocks submitted to a channel via the
|
||||
.Fn dispatch_io_read
|
||||
or
|
||||
.Fn dispatch_io_write
|
||||
functions will be executed one or more times depending on system load and the
|
||||
channel's configuration settings (see
|
||||
.Xr dispatch_io_create 3
|
||||
for details). The handler block need not be reentrant safe,
|
||||
no new I/O handler instance is submitted until the previously enqueued handler
|
||||
block has returned.
|
||||
.Pp
|
||||
The dispatch
|
||||
.Va data
|
||||
object passed to an I/O handler block will be released by the system when the
|
||||
block returns, if access to the memory buffer it represents is needed outside
|
||||
of the handler, the handler block must retain the data object or create a new
|
||||
(e.g.\& concatenated) data object from it (see
|
||||
.Xr dispatch_data_create 3
|
||||
for details).
|
||||
.Pp
|
||||
Once an I/O handler block is invoked with the
|
||||
.Va done
|
||||
flag set, the associated I/O operation is complete and that handler block will
|
||||
not be run again. If an unrecoverable error occurs while performing the I/O
|
||||
operation, the handler block will be submitted with the
|
||||
.Va done
|
||||
flag set and the appropriate POSIX error code in the
|
||||
.Va error
|
||||
parameter. An invocation of a handler block with the
|
||||
.Va done
|
||||
flag set, zero
|
||||
.Va error
|
||||
and
|
||||
.Va data
|
||||
set to
|
||||
.Vt dispatch_data_empty
|
||||
indicates that the I/O operation has encountered EOF.
|
||||
.Sh SEE ALSO
|
||||
.Xr dispatch 3 ,
|
||||
.Xr dispatch_data_create 3 ,
|
||||
.Xr dispatch_io_create 3 ,
|
||||
.Xr dispatch_read 3 ,
|
||||
.Xr fread 3
|
||||
190
Telegram/ThirdParty/dispatch/man/dispatch_object.3
vendored
Normal file
190
Telegram/ThirdParty/dispatch/man/dispatch_object.3
vendored
Normal file
@@ -0,0 +1,190 @@
|
||||
.\" Copyright (c) 2008-2012 Apple Inc. All rights reserved.
|
||||
.Dd March 1, 2012
|
||||
.Dt dispatch_object 3
|
||||
.Os Darwin
|
||||
.Sh NAME
|
||||
.Nm dispatch_object
|
||||
.Nd General manipulation of dispatch objects
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <dispatch/dispatch.h>
|
||||
.Ft void
|
||||
.Fo dispatch_retain
|
||||
.Fa "dispatch_object_t object"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_release
|
||||
.Fa "dispatch_object_t object"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_suspend
|
||||
.Fa "dispatch_object_t object"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_resume
|
||||
.Fa "dispatch_object_t object"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_activate
|
||||
.Fa "dispatch_object_t object"
|
||||
.Fc
|
||||
.Ft "void *"
|
||||
.Fo dispatch_get_context
|
||||
.Fa "dispatch_object_t object"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_set_context
|
||||
.Fa "dispatch_object_t object"
|
||||
.Fa "void *context"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_set_finalizer_f
|
||||
.Fa "dispatch_object_t object"
|
||||
.Fa "dispatch_function_t finalizer"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
Dispatch objects share functions for coordinating memory management, suspension,
|
||||
cancellation and context pointers.
|
||||
.Sh MEMORY MANAGEMENT
|
||||
Objects returned by creation functions in the dispatch framework may be
|
||||
uniformly retained and released with the functions
|
||||
.Fn dispatch_retain
|
||||
and
|
||||
.Fn dispatch_release
|
||||
respectively.
|
||||
.Pp
|
||||
The dispatch framework does not guarantee that any given client has the last or
|
||||
only reference to a given object. Objects may be retained internally by the
|
||||
system.
|
||||
.Ss INTEGRATION WITH OBJECTIVE-C
|
||||
.Bd -filled -offset indent
|
||||
When building with an Objective-C or Objective-C++ compiler, dispatch objects
|
||||
are declared as Objective-C types. This results in the following differences
|
||||
compared to building as plain C/C++:
|
||||
.Bl -dash
|
||||
.It
|
||||
if Objective-C Automated Reference Counting is enabled, dispatch objects are
|
||||
memory managed by the Objective-C runtime and explicit calls to the
|
||||
.Fn dispatch_retain
|
||||
and
|
||||
.Fn dispatch_release
|
||||
functions will produce build errors.
|
||||
.Pp
|
||||
.Em Note :
|
||||
when ARC is enabled, care needs to be taken with dispatch API returning an
|
||||
interior pointer that is only valid as long as an associated object has not
|
||||
been released. If that object is held in a variable with automatic storage, it
|
||||
may need to be annotated with the
|
||||
.Li objc_precise_lifetime
|
||||
attribute, or stored in a
|
||||
.Li __strong
|
||||
instance variable instead, to ensure that the object is not prematurely
|
||||
released. The functions returning interior pointers are
|
||||
.Xr dispatch_data_create_map 3
|
||||
and
|
||||
.Xr dispatch_data_apply 3 .
|
||||
.It
|
||||
the Blocks runtime automatically retains and releases dispatch objects captured
|
||||
by blocks upon
|
||||
.Fn Block_copy
|
||||
and
|
||||
.Fn Block_release ,
|
||||
e.g.\& as performed during asynchronous execution of a block via
|
||||
.Xr dispatch_async 3 .
|
||||
.Pp
|
||||
.Em Note :
|
||||
retain cycles may be encountered if dispatch source objects are captured by
|
||||
their handler blocks; these cycles can be broken by declaring the captured
|
||||
object
|
||||
.Li __weak
|
||||
or by calling
|
||||
.Xr dispatch_source_cancel 3
|
||||
to cause its handler blocks to be released explicitly.
|
||||
.It
|
||||
dispatch objects can be added directly to Cocoa collections, and their
|
||||
lifetime is tracked by the Objective-C static analyzer.
|
||||
.El
|
||||
.Pp
|
||||
Integration of dispatch objects with Objective-C requires targeting Mac\ OS\ X
|
||||
10.8 or later, and is disabled when building for the legacy Objective-C runtime.
|
||||
It can also be disabled manually by using compiler options to define the
|
||||
.Dv OS_OBJECT_USE_OBJC
|
||||
preprocessor macro to
|
||||
.Li 0 .
|
||||
.Ed
|
||||
.Pp
|
||||
.Em Important :
|
||||
When building with a plain C/C++ compiler or when integration with Objective-C
|
||||
is disabled, dispatch objects are
|
||||
.Em not
|
||||
automatically retained and released when captured by a block. Therefore, when a
|
||||
dispatch object is captured by a block that will be executed asynchronously,
|
||||
the object must be manually retained and released:
|
||||
.Pp
|
||||
.Bd -literal -offset indent
|
||||
dispatch_retain(object);
|
||||
dispatch_async(queue, ^{
|
||||
do_something_with_object(object);
|
||||
dispatch_release(object);
|
||||
});
|
||||
.Ed
|
||||
.Sh ACTIVATION
|
||||
Dispatch objects such as queues and sources may be created in an inactive
|
||||
state. Objects in this state must be activated before any blocks
|
||||
associated with them will be invoked. Calling
|
||||
.Fn dispatch_activate
|
||||
on an active object has no effect.
|
||||
.Pp
|
||||
Changing attributes such as the target queue or a source handler is no longer permitted
|
||||
once the object has been activated (see
|
||||
.Xr dispatch_set_target_queue 3 ,
|
||||
.Xr dispatch_source_set_event_handler 3 ).
|
||||
.Sh SUSPENSION
|
||||
The invocation of blocks on dispatch queues or dispatch sources may be suspended
|
||||
or resumed with the functions
|
||||
.Fn dispatch_suspend
|
||||
and
|
||||
.Fn dispatch_resume
|
||||
respectively. Other dispatch objects do not support suspension.
|
||||
.Pp
|
||||
The dispatch framework always checks the suspension status before executing a
|
||||
block, but such changes never affect a block during execution (non-preemptive).
|
||||
Therefore the suspension of an object is asynchronous, unless it is performed
|
||||
from the context of the target queue for the given object.
|
||||
The result of suspending or resuming an object that is not a dispatch queue or
|
||||
a dispatch source is undefined.
|
||||
.Pp
|
||||
.Em Important :
|
||||
suspension applies to all aspects of the dispatch object life cycle, including
|
||||
the finalizer function and cancellation handler. Suspending an object causes it
|
||||
to be retained and resuming an object causes it to be released. Therefore it is
|
||||
important to balance calls to
|
||||
.Fn dispatch_suspend
|
||||
and
|
||||
.Fn dispatch_resume
|
||||
such that the dispatch object is fully resumed when the last reference is
|
||||
released. The result of releasing all references to a dispatch object while in
|
||||
an inactive or suspended state is undefined.
|
||||
.Sh CONTEXT POINTERS
|
||||
Dispatch objects support supplemental context pointers. The value of the
|
||||
context pointer may be retrieved and updated with
|
||||
.Fn dispatch_get_context
|
||||
and
|
||||
.Fn dispatch_set_context
|
||||
respectively.
|
||||
The
|
||||
.Fn dispatch_set_finalizer_f
|
||||
specifies an optional per-object finalizer function that is invoked
|
||||
asynchronously if the context pointer is not NULL when the last
|
||||
reference to the object is released.
|
||||
This gives the
|
||||
application an opportunity to free the context data associated with the object.
|
||||
The finalizer will be run on the object's target queue.
|
||||
.Sh SEE ALSO
|
||||
.Xr dispatch 3 ,
|
||||
.Xr dispatch_async 3 ,
|
||||
.Xr dispatch_group_create 3 ,
|
||||
.Xr dispatch_queue_create 3 ,
|
||||
.Xr dispatch_semaphore_create 3 ,
|
||||
.Xr dispatch_set_target_queue 3 ,
|
||||
.Xr dispatch_source_cancel 3 ,
|
||||
.Xr dispatch_source_create 3
|
||||
46
Telegram/ThirdParty/dispatch/man/dispatch_once.3
vendored
Normal file
46
Telegram/ThirdParty/dispatch/man/dispatch_once.3
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
.\" Copyright (c) 2008-2009 Apple Inc. All rights reserved.
|
||||
.Dd May 1, 2009
|
||||
.Dt dispatch_once 3
|
||||
.Os Darwin
|
||||
.Sh NAME
|
||||
.Nm dispatch_once
|
||||
.Nd execute a block only once
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <dispatch/dispatch.h>
|
||||
.Ft void
|
||||
.Fo dispatch_once
|
||||
.Fa "dispatch_once_t *predicate" "void (^block)(void)"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_once_f
|
||||
.Fa "dispatch_once_t *predicate" "void *context" "void (*function)(void *)"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn dispatch_once
|
||||
function provides a simple and efficient mechanism to run an initializer
|
||||
exactly once, similar to
|
||||
.Xr pthread_once 3 .
|
||||
Well designed code hides the use of lazy initialization.
|
||||
For example:
|
||||
.Bd -literal
|
||||
FILE *getlogfile(void)
|
||||
{
|
||||
static dispatch_once_t pred;
|
||||
static FILE *logfile;
|
||||
|
||||
dispatch_once(&pred, ^{
|
||||
logfile = fopen(MY_LOG_FILE, "a");
|
||||
});
|
||||
|
||||
return logfile;
|
||||
}
|
||||
.Ed
|
||||
.Pp
|
||||
.Sh FUNDAMENTALS
|
||||
The
|
||||
.Fn dispatch_once
|
||||
function is a wrapper around
|
||||
.Fn dispatch_once_f .
|
||||
.Sh SEE ALSO
|
||||
.Xr dispatch 3
|
||||
371
Telegram/ThirdParty/dispatch/man/dispatch_queue_create.3
vendored
Normal file
371
Telegram/ThirdParty/dispatch/man/dispatch_queue_create.3
vendored
Normal file
@@ -0,0 +1,371 @@
|
||||
.\" Copyright (c) 2008-2012 Apple Inc. All rights reserved.
|
||||
.Dd May 1, 2008
|
||||
.Dt dispatch_queue_create 3
|
||||
.Os Darwin
|
||||
.Sh NAME
|
||||
.Nm dispatch_queue_create ,
|
||||
.Nm dispatch_queue_get_label ,
|
||||
.Nm dispatch_get_current_queue ,
|
||||
.Nm dispatch_get_global_queue ,
|
||||
.Nm dispatch_get_main_queue ,
|
||||
.Nm dispatch_main ,
|
||||
.Nm dispatch_set_target_queue
|
||||
.Nd where blocks are scheduled for execution
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <dispatch/dispatch.h>
|
||||
.Ft dispatch_queue_t
|
||||
.Fo dispatch_queue_create
|
||||
.Fa "const char *label" "dispatch_queue_attr_t attr"
|
||||
.Fc
|
||||
.Ft "const char *"
|
||||
.Fo dispatch_queue_get_label
|
||||
.Fa "dispatch_queue_t queue"
|
||||
.Fc
|
||||
.Ft dispatch_queue_t
|
||||
.Fo dispatch_get_global_queue
|
||||
.Fa "long priority"
|
||||
.Fa "unsigned long flags"
|
||||
.Fc
|
||||
.Ft dispatch_queue_t
|
||||
.Fo dispatch_get_main_queue
|
||||
.Fa void
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_main
|
||||
.Fa void
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_set_target_queue
|
||||
.Fa "dispatch_object_t object"
|
||||
.Fa "dispatch_queue_t target"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
Queues are the fundamental mechanism for scheduling blocks for execution within
|
||||
the
|
||||
.Xr dispatch 3
|
||||
framework.
|
||||
.Pp
|
||||
All blocks submitted to dispatch queues are dequeued in FIFO order.
|
||||
Queues created with the
|
||||
.Dv DISPATCH_QUEUE_SERIAL
|
||||
attribute wait for the previously dequeued block to complete before dequeuing
|
||||
the next block. A queue with this FIFO completion behavior is usually simply
|
||||
described as a "serial queue." All memory writes performed by a block dispatched
|
||||
to a serial queue are guaranteed to be visible to subsequent blocks dispatched
|
||||
to the same queue. Queues are not bound to any specific thread of execution and
|
||||
blocks submitted to independent queues may execute concurrently.
|
||||
.Pp
|
||||
Queues created with the
|
||||
.Dv DISPATCH_QUEUE_CONCURRENT
|
||||
attribute may execute dequeued blocks concurrently and support barrier blocks
|
||||
submitted with the dispatch barrier API.
|
||||
.Sh CREATION
|
||||
Queues are created with the
|
||||
.Fn dispatch_queue_create
|
||||
function. Queues, like all dispatch objects, are reference counted and newly
|
||||
created queues have a reference count of one.
|
||||
.Pp
|
||||
The optional
|
||||
.Fa label
|
||||
argument is used to describe the purpose of the queue and is useful during
|
||||
debugging and performance analysis. If a label is provided, it is copied.
|
||||
By convention, clients should pass a reverse DNS style label. For example:
|
||||
.Pp
|
||||
.Bd -literal -offset indent
|
||||
my_queue = dispatch_queue_create("com.example.subsystem.taskXYZ",
|
||||
DISPATCH_QUEUE_SERIAL);
|
||||
.Ed
|
||||
.Pp
|
||||
The
|
||||
.Fa attr
|
||||
argument specifies the type of queue to create and must be either
|
||||
.Dv DISPATCH_QUEUE_SERIAL
|
||||
or
|
||||
.Dv DISPATCH_QUEUE_CONCURRENT .
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_queue_get_label
|
||||
function returns the label provided when the given
|
||||
.Fa queue
|
||||
was created (or an empty C string if no label was provided at creation).
|
||||
Passing the constant
|
||||
.Dv DISPATCH_CURRENT_QUEUE_LABEL
|
||||
to
|
||||
.Fn dispatch_queue_get_label
|
||||
returns the label of the current queue.
|
||||
.Sh SUSPENSION
|
||||
Queues may be temporarily suspended and resumed with the functions
|
||||
.Fn dispatch_suspend
|
||||
and
|
||||
.Fn dispatch_resume
|
||||
respectively. Suspension is checked prior to block execution and is
|
||||
.Em not
|
||||
preemptive.
|
||||
.Sh MAIN QUEUE
|
||||
The dispatch framework provides a default serial queue for the application to
|
||||
use. This queue is accessed via the
|
||||
.Fn dispatch_get_main_queue
|
||||
function.
|
||||
.Pp
|
||||
Programs must call
|
||||
.Fn dispatch_main
|
||||
at the end of
|
||||
.Fn main
|
||||
in order to process blocks submitted to the main queue. (See the
|
||||
.Sx COMPATIBILITY
|
||||
section for exceptions.) The
|
||||
.Fn dispatch_main
|
||||
function never returns.
|
||||
.Sh GLOBAL CONCURRENT QUEUES
|
||||
Unlike the main queue or queues allocated with
|
||||
.Fn dispatch_queue_create ,
|
||||
the global concurrent queues schedule blocks as soon as threads become
|
||||
available (non-FIFO completion order). Four global concurrent queues are
|
||||
provided, representing the following priority bands:
|
||||
.Bl -bullet -compact -offset indent
|
||||
.It
|
||||
DISPATCH_QUEUE_PRIORITY_HIGH
|
||||
.It
|
||||
DISPATCH_QUEUE_PRIORITY_DEFAULT
|
||||
.It
|
||||
DISPATCH_QUEUE_PRIORITY_LOW
|
||||
.It
|
||||
DISPATCH_QUEUE_PRIORITY_BACKGROUND
|
||||
.El
|
||||
.Pp
|
||||
The priority of a global concurrent queue controls the scheduling priority of
|
||||
the threads created by the system to invoke the blocks submitted to that queue.
|
||||
Global queues with lower priority will be scheduled for execution after all
|
||||
global queues with higher priority have been scheduled. Additionally, items on
|
||||
the background priority global queue will execute on threads with background
|
||||
state as described in
|
||||
.Xr setpriority 2
|
||||
(i.e.\& disk I/O is throttled and the thread's scheduling priority is set to
|
||||
lowest value).
|
||||
.Pp
|
||||
Use the
|
||||
.Fn dispatch_get_global_queue
|
||||
function to obtain the global queue of given priority. The
|
||||
.Fa flags
|
||||
argument is reserved for future use and must be zero. Passing any value other
|
||||
than zero may result in a NULL return value.
|
||||
.Sh TARGET QUEUE
|
||||
The
|
||||
.Fn dispatch_set_target_queue
|
||||
function updates the target queue of the given dispatch object. The target
|
||||
queue of an object is responsible for processing the object.
|
||||
.Pp
|
||||
The new target queue is retained by the given object before the previous target
|
||||
queue is released. The new target queue setting will take effect between block
|
||||
executions on the object, but not in the middle of any existing block executions
|
||||
(non-preemptive).
|
||||
.Pp
|
||||
The default target queue of all dispatch objects created by the application is
|
||||
the default priority global concurrent queue. To reset an object's target queue
|
||||
to the default, pass the
|
||||
.Dv DISPATCH_TARGET_QUEUE_DEFAULT
|
||||
constant to
|
||||
.Fn dispatch_set_target_queue .
|
||||
.Pp
|
||||
The priority of a dispatch queue is inherited from its target queue.
|
||||
In order to change the priority of a queue created with
|
||||
.Fn dispatch_queue_create ,
|
||||
use the
|
||||
.Fn dispatch_get_global_queue
|
||||
function to obtain a target queue of the desired priority.
|
||||
.Pp
|
||||
Blocks submitted to a serial queue whose target queue is another serial queue
|
||||
will not be invoked concurrently with blocks submitted to the target queue or
|
||||
to any other queue with that same target queue.
|
||||
.Pp
|
||||
The target queue of a dispatch source specifies where its event handler and
|
||||
cancellation handler blocks will be submitted. See
|
||||
.Xr dispatch_source_create 3
|
||||
for more information about dispatch sources.
|
||||
.Pp
|
||||
The target queue of a dispatch I/O channel specifies the priority of the global
|
||||
queue where its I/O operations are executed. See
|
||||
.Xr dispatch_io_create 3
|
||||
for more information about dispatch I/O channels.
|
||||
.Pp
|
||||
For all other dispatch object types, the only function of the target queue is
|
||||
to determine where an object's finalizer function is invoked.
|
||||
.Pp
|
||||
The result of passing the main queue or a global concurrent queue as the first
|
||||
argument of
|
||||
.Fn dispatch_set_target_queue
|
||||
is undefined.
|
||||
.Pp
|
||||
Directly or indirectly setting the target queue of a dispatch queue to itself is
|
||||
undefined.
|
||||
.Sh DEPRECATED FUNCTIONS
|
||||
The following functions are deprecated and will be removed in a future release:
|
||||
.Bl -item
|
||||
.It
|
||||
.Ft dispatch_queue_t
|
||||
.Fn dispatch_get_current_queue void ;
|
||||
.El
|
||||
.Pp
|
||||
.Fn dispatch_get_current_queue
|
||||
always returns a valid queue. When called from within a block
|
||||
submitted to a dispatch queue, that queue will be returned. If this function is
|
||||
called from the main thread before
|
||||
.Fn dispatch_main
|
||||
is called, then the result of
|
||||
.Fn dispatch_get_main_queue
|
||||
is returned. In all other cases, the default target queue will be returned.
|
||||
.Pp
|
||||
The use of
|
||||
.Fn dispatch_get_current_queue
|
||||
is strongly discouraged except for debugging and logging purposes. Code must not
|
||||
make any assumptions about the queue returned, unless it is one of the global
|
||||
queues or a queue the code has itself created. The returned queue may have
|
||||
arbitrary policies that may surprise code that tries to schedule work with the
|
||||
queue. The list of policies includes, but is not limited to, queue width (i.e.
|
||||
serial vs. concurrent), scheduling priority, security credential or filesystem
|
||||
configuration. This function is deprecated and will be removed in a future
|
||||
release.
|
||||
.Pp
|
||||
It is equally unsafe for code to assume that synchronous execution onto a queue
|
||||
is safe from deadlock if that queue is not the one returned by
|
||||
.Fn dispatch_get_current_queue .
|
||||
.Pp
|
||||
The result of
|
||||
.Fn dispatch_get_main_queue
|
||||
may or may not equal the result of
|
||||
.Fn dispatch_get_current_queue
|
||||
when called on the main thread. Comparing the two is not a valid way to test
|
||||
whether code is executing on the main thread. Foundation/AppKit programs should
|
||||
use [NSThread isMainThread]. POSIX programs may use
|
||||
.Xr pthread_main_np 3 .
|
||||
.Pp
|
||||
.Fn dispatch_get_current_queue
|
||||
may return a queue owned by a different subsystem which has already had all
|
||||
external references to it released. While such a queue will continue to exist
|
||||
until all blocks submitted to it have completed, attempting to retain it is
|
||||
forbidden and will trigger an assertion. If Objective-C Automatic Reference
|
||||
Counting is enabled, any use of the object returned by
|
||||
.Fn dispatch_get_current_queue
|
||||
will cause retain calls to be automatically generated, so the use of
|
||||
.Fn dispatch_get_current_queue
|
||||
for any reason in code built with ARC is particularly strongly discouraged.
|
||||
.Sh COMPATIBILITY
|
||||
Cocoa applications need not call
|
||||
.Fn dispatch_main .
|
||||
Blocks submitted to the main queue will be executed as part of the "common
|
||||
modes" of the application's main NSRunLoop or CFRunLoop.
|
||||
However, blocks submitted to the main queue in applications using
|
||||
.Fn dispatch_main
|
||||
are not guaranteed to execute on the main thread.
|
||||
.Pp
|
||||
The dispatch framework is a pure C level API. As a result, it does not catch
|
||||
exceptions generated by higher level languages such as Objective-C or C++.
|
||||
Applications
|
||||
.Em MUST
|
||||
catch all exceptions before returning from a block submitted to a dispatch
|
||||
queue; otherwise the process will be terminated with an uncaught exception.
|
||||
.Pp
|
||||
The dispatch framework manages the relationship between dispatch queues and
|
||||
threads of execution. As a result, applications
|
||||
.Em MUST NOT
|
||||
delete or mutate objects that they did not create. The following interfaces
|
||||
.Em MUST NOT
|
||||
be called by blocks submitted to a dispatch queue:
|
||||
.Bl -bullet -offset indent
|
||||
.It
|
||||
.Fn pthread_cancel
|
||||
.It
|
||||
.Fn pthread_detach
|
||||
.It
|
||||
.Fn pthread_join
|
||||
.It
|
||||
.Fn pthread_kill
|
||||
.It
|
||||
.Fn pthread_exit
|
||||
.El
|
||||
.Pp
|
||||
Applications
|
||||
.Em MAY
|
||||
call the following interfaces from a block submitted to a dispatch queue if
|
||||
and only if they restore the thread to its original state before returning:
|
||||
.Bl -bullet -offset indent
|
||||
.It
|
||||
.Fn pthread_setcancelstate
|
||||
.It
|
||||
.Fn pthread_setcanceltype
|
||||
.It
|
||||
.Fn pthread_setschedparam
|
||||
.It
|
||||
.Fn pthread_sigmask
|
||||
.It
|
||||
.Fn pthread_setugid_np
|
||||
.El
|
||||
.Pp
|
||||
Applications
|
||||
.Em MUST NOT
|
||||
rely on the following interfaces returning predictable results between
|
||||
invocations of blocks submitted to a dispatch queue:
|
||||
.Bl -bullet -offset indent
|
||||
.It
|
||||
.Fn pthread_self
|
||||
.It
|
||||
.Fn pthread_getschedparam
|
||||
.It
|
||||
.Fn pthread_get_stacksize_np
|
||||
.It
|
||||
.Fn pthread_get_stackaddr_np
|
||||
.It
|
||||
.Fn pthread_mach_thread_np
|
||||
.It
|
||||
.Fn pthread_from_mach_thread_np
|
||||
.El
|
||||
.Pp
|
||||
While the result of
|
||||
.Fn pthread_self
|
||||
may change between invocations of blocks, the value will not change during the
|
||||
execution of any single block. Because the underlying thread may change beteween
|
||||
block invocations on a single queue, using per-thread data as an out-of-band
|
||||
return value is error prone. In other words, the result of calling
|
||||
.Fn pthread_setspecific
|
||||
and
|
||||
.Fn pthread_getspecific
|
||||
is well defined within a signle block, but not across multiple blocks. Also,
|
||||
one cannot make any assumptions about when the destructor passed to
|
||||
.Fn pthread_key_create
|
||||
is called. The destructor may be called between the invocation of blocks on
|
||||
the same queue, or during the idle state of a process.
|
||||
.Pp
|
||||
The following example code correctly handles per-thread return values:
|
||||
.Bd -literal -offset indent
|
||||
__block int r;
|
||||
__block int e;
|
||||
dispatch_sync(queue, ^{
|
||||
r = kill(1, 0);
|
||||
// Copy the per-thread return value to the callee thread
|
||||
e = errno;
|
||||
});
|
||||
printf("kill(1,0) returned %d and errno %d\n", r, e);
|
||||
.Ed
|
||||
.Pp
|
||||
Note that in the above example
|
||||
.Va errno
|
||||
is a per-thread variable and must be copied out explicitly as the block may be
|
||||
invoked on different thread of execution than the caller. Another example of
|
||||
per-thread data that would need to be copied is the use of
|
||||
.Fn getpwnam
|
||||
instead of
|
||||
.Fn getpwnam_r .
|
||||
.Pp
|
||||
As an optimization,
|
||||
.Fn dispatch_sync
|
||||
invokes the block on the current thread when possible. In this case, the thread
|
||||
specific data such as
|
||||
.Va errno
|
||||
may persist from the block until back to the caller. Great care should be taken
|
||||
not to accidentally rely on this side-effect.
|
||||
.Pp
|
||||
.Sh SEE ALSO
|
||||
.Xr dispatch 3 ,
|
||||
.Xr dispatch_async 3 ,
|
||||
.Xr dispatch_object 3 ,
|
||||
.Xr dispatch_source_create 3
|
||||
123
Telegram/ThirdParty/dispatch/man/dispatch_read.3
vendored
Normal file
123
Telegram/ThirdParty/dispatch/man/dispatch_read.3
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
.\" Copyright (c) 2010 Apple Inc. All rights reserved.
|
||||
.Dd December 1, 2010
|
||||
.Dt dispatch_read 3
|
||||
.Os Darwin
|
||||
.Sh NAME
|
||||
.Nm dispatch_read ,
|
||||
.Nm dispatch_write
|
||||
.Nd asynchronously read from and write to file descriptors
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <dispatch/dispatch.h>
|
||||
.Ft void
|
||||
.Fo dispatch_read
|
||||
.Fa "int fd"
|
||||
.Fa "size_t length"
|
||||
.Fa "dispatch_queue_t queue"
|
||||
.Fa "void (^handler)(dispatch_data_t data, int error)"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_write
|
||||
.Fa "int fd"
|
||||
.Fa "dispatch_data_t data"
|
||||
.Fa "dispatch_queue_t queue"
|
||||
.Fa "void (^handler)(dispatch_data_t data, int error))"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn dispatch_read
|
||||
and
|
||||
.Fn dispatch_write
|
||||
functions asynchronously read from and write to POSIX file descriptors. They
|
||||
can be thought of as asynchronous, callback-based versions of the
|
||||
.Fn fread
|
||||
and
|
||||
.Fn fwrite
|
||||
functions provided by the standard C library. They are convenience functions
|
||||
based on the
|
||||
.Xr dispatch_io_read 3
|
||||
and
|
||||
.Xr dispatch_io_write 3
|
||||
functions, intended for simple one-shot read or write requests. Multiple
|
||||
request on the same file desciptor are better handled with the full underlying
|
||||
dispatch I/O channel functions.
|
||||
.Sh BEHAVIOR
|
||||
The
|
||||
.Fn dispatch_read
|
||||
function schedules an asynchronous read operation on the file descriptor
|
||||
.Va fd .
|
||||
Once the file descriptor is readable, the system will read as much data as is
|
||||
currently available, up to the specified
|
||||
.Va length ,
|
||||
starting at the current file pointer position. The given
|
||||
.Va handler
|
||||
block will be submitted to
|
||||
.Va queue
|
||||
when the operation completes or an error occurs. The block will be passed a
|
||||
dispatch
|
||||
.Va data
|
||||
object with the result of the read operation. If an error occurred while
|
||||
reading from the file descriptor, the
|
||||
.Va error
|
||||
parameter to the block will be set to the appropriate POSIX error code and
|
||||
.Va data
|
||||
will contain any data that could be read successfully. If the file pointer
|
||||
position is at end-of-file, emtpy
|
||||
.Va data
|
||||
and zero
|
||||
.Va error
|
||||
will be passed to the handler block.
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_write
|
||||
function schedules an asynchronous write operation on the file descriptor
|
||||
.Va fd .
|
||||
The system will attempt to write the entire contents of the provided
|
||||
.Va data
|
||||
object to
|
||||
.Va fd
|
||||
at the current file pointer position. The given
|
||||
.Va handler
|
||||
block will be submitted to
|
||||
.Va queue
|
||||
when the operation completes or an error occurs. If the write operation
|
||||
completed successfully, the
|
||||
.Va error
|
||||
parameter to the block will be set to zero, otherwise it will be set to the
|
||||
appropriate POSIX error code and the
|
||||
.Va data
|
||||
parameter will contain any data that could not be written.
|
||||
.Sh CAVEATS
|
||||
The
|
||||
.Va data
|
||||
object passed to a
|
||||
.Va handler
|
||||
block is released by the system when the block returns. If
|
||||
.Va data
|
||||
is needed outside of the handler block, it must concatenate, copy, or retain
|
||||
it.
|
||||
.Pp
|
||||
Once an asynchronous read or write operation has been submitted on a file
|
||||
descriptor
|
||||
.Va fd ,
|
||||
the system takes control of that file descriptor until the
|
||||
.Va handler
|
||||
block is executed. During this time the application must not manipulate
|
||||
.Va fd
|
||||
directly, in particular it is only safe to close
|
||||
.Va fd
|
||||
from the handler block (or after it has returned).
|
||||
.Pp
|
||||
If multiple asynchronous read or write operations are submitted to the same
|
||||
file descriptor, they will be performed in order, but their handlers will only
|
||||
be submitted once all operations have completed and control over the file
|
||||
descriptor has been relinquished. For details on this and on the interaction
|
||||
with dispatch I/O channels created from the same file descriptor, see
|
||||
.Sx FILEDESCRIPTOR OWNERSHIP
|
||||
in
|
||||
.Xr dispatch_io_create 3 .
|
||||
.Sh SEE ALSO
|
||||
.Xr dispatch 3 ,
|
||||
.Xr dispatch_data_create 3 ,
|
||||
.Xr dispatch_io_create 3 ,
|
||||
.Xr dispatch_io_read 3 ,
|
||||
.Xr fread 3
|
||||
121
Telegram/ThirdParty/dispatch/man/dispatch_semaphore_create.3
vendored
Normal file
121
Telegram/ThirdParty/dispatch/man/dispatch_semaphore_create.3
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
.\" Copyright (c) 2008-2012 Apple Inc. All rights reserved.
|
||||
.Dd May 1, 2009
|
||||
.Dt dispatch_semaphore_create 3
|
||||
.Os Darwin
|
||||
.Sh NAME
|
||||
.Nm dispatch_semaphore_create ,
|
||||
.Nm dispatch_semaphore_signal ,
|
||||
.Nm dispatch_semaphore_wait
|
||||
.Nd synchronized counting semaphore
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <dispatch/dispatch.h>
|
||||
.Ft dispatch_semaphore_t
|
||||
.Fo dispatch_semaphore_create
|
||||
.Fa "long count"
|
||||
.Fc
|
||||
.Ft long
|
||||
.Fo dispatch_semaphore_signal
|
||||
.Fa "dispatch_semaphore_t semaphore"
|
||||
.Fc
|
||||
.Ft long
|
||||
.Fo dispatch_semaphore_wait
|
||||
.Fa "dispatch_semaphore_t semaphore" "dispatch_time_t timeout"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
Dispatch semaphores are used to synchronize threads.
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_semaphore_wait
|
||||
function decrements the semaphore. If the resulting value is less than zero,
|
||||
it waits for a signal from a thread that increments the semaphore by calling
|
||||
.Fn dispatch_semaphore_signal
|
||||
before returning.
|
||||
The
|
||||
.Fa timeout
|
||||
parameter is creatable with the
|
||||
.Xr dispatch_time 3
|
||||
or
|
||||
.Xr dispatch_walltime 3
|
||||
functions. If the timeout is reached without a signal being received, the semaphore
|
||||
is re-incremented before the function returns.
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_semaphore_signal
|
||||
function increments the counting semaphore. If the previous value was less than zero,
|
||||
it wakes one of the threads that are waiting in
|
||||
.Fn dispatch_semaphore_wait
|
||||
before returning.
|
||||
.Sh COMPLETION SYNCHRONIZATION
|
||||
If the
|
||||
.Fa count
|
||||
parameter is equal to zero, then the semaphore is useful for synchronizing
|
||||
completion of work.
|
||||
For example:
|
||||
.Bd -literal -offset indent
|
||||
sema = dispatch_semaphore_create(0);
|
||||
|
||||
dispatch_async(queue, ^{
|
||||
foo();
|
||||
dispatch_semaphore_signal(sema);
|
||||
});
|
||||
|
||||
bar();
|
||||
|
||||
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
|
||||
.Ed
|
||||
.Sh FINITE RESOURCE POOL
|
||||
If the
|
||||
.Fa count
|
||||
parameter is greater than zero, then the semaphore is useful for managing a
|
||||
finite pool of resources.
|
||||
For example, a library that wants to limit Unix descriptor usage:
|
||||
.Bd -literal -offset indent
|
||||
sema = dispatch_semaphore_create(getdtablesize() / 4);
|
||||
.Ed
|
||||
.Pp
|
||||
At each Unix FD allocation:
|
||||
.Bd -literal -offset indent
|
||||
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
|
||||
fd = open("/etc/services", O_RDONLY);
|
||||
.Ed
|
||||
.Pp
|
||||
When each FD is closed:
|
||||
.Bd -literal -offset indent
|
||||
close(fd);
|
||||
dispatch_semaphore_signal(sema);
|
||||
.Ed
|
||||
.Sh RETURN VALUES
|
||||
The
|
||||
.Fn dispatch_semaphore_create
|
||||
function returns NULL if no memory is available or if the
|
||||
.Fa count
|
||||
parameter is less than zero.
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_semaphore_signal
|
||||
function returns non-zero when a thread is woken.
|
||||
Otherwise, zero is returned.
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_semaphore_wait
|
||||
function returns zero upon success and non-zero after the timeout expires. If
|
||||
the timeout is DISPATCH_TIME_FOREVER, then
|
||||
.Fn dispatch_semaphore_wait
|
||||
waits forever and always returns zero.
|
||||
.Sh MEMORY MODEL
|
||||
Dispatch semaphores are retained and released via calls to
|
||||
.Fn dispatch_retain
|
||||
and
|
||||
.Fn dispatch_release .
|
||||
.Sh CAVEATS
|
||||
Unbalanced dispatch semaphores cannot be released.
|
||||
For a given semaphore, calls to
|
||||
.Fn dispatch_semaphore_signal
|
||||
and
|
||||
.Fn dispatch_semaphore_wait
|
||||
must be balanced before
|
||||
.Fn dispatch_release
|
||||
is called on it.
|
||||
.Sh SEE ALSO
|
||||
.Xr dispatch 3 ,
|
||||
.Xr dispatch_object 3
|
||||
587
Telegram/ThirdParty/dispatch/man/dispatch_source_create.3
vendored
Normal file
587
Telegram/ThirdParty/dispatch/man/dispatch_source_create.3
vendored
Normal file
@@ -0,0 +1,587 @@
|
||||
.\" Copyright (c) 2008-2013 Apple Inc. All rights reserved.
|
||||
.Dd May 1, 2009
|
||||
.Dt dispatch_source_create 3
|
||||
.Os Darwin
|
||||
.Sh NAME
|
||||
.Nm dispatch_source_create
|
||||
.Nd dispatch event sources
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <dispatch/dispatch.h>
|
||||
.Ft dispatch_source_t
|
||||
.Fo dispatch_source_create
|
||||
.Fa "dispatch_source_type_t type"
|
||||
.Fa "uintptr_t handle"
|
||||
.Fa "unsigned long mask"
|
||||
.Fa "dispatch_queue_t queue"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_source_set_event_handler
|
||||
.Fa "dispatch_source_t source"
|
||||
.Fa "void (^block)(void)"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_source_set_event_handler_f
|
||||
.Fa "dispatch_source_t source"
|
||||
.Fa "void (*function)(void *)"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_source_set_registration_handler
|
||||
.Fa "dispatch_source_t source"
|
||||
.Fa "void (^block)(void)"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_source_set_registration_handler_f
|
||||
.Fa "dispatch_source_t source"
|
||||
.Fa "void (*function)(void *)"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_source_set_cancel_handler
|
||||
.Fa "dispatch_source_t source"
|
||||
.Fa "void (^block)(void)"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_source_set_cancel_handler_f
|
||||
.Fa "dispatch_source_t source"
|
||||
.Fa "void (*function)(void *)"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_source_cancel
|
||||
.Fa "dispatch_source_t source"
|
||||
.Fc
|
||||
.Ft long
|
||||
.Fo dispatch_source_testcancel
|
||||
.Fa "dispatch_source_t source"
|
||||
.Fc
|
||||
.Ft uintptr_t
|
||||
.Fo dispatch_source_get_handle
|
||||
.Fa "dispatch_source_t source"
|
||||
.Fc
|
||||
.Ft "unsigned long"
|
||||
.Fo dispatch_source_get_mask
|
||||
.Fa "dispatch_source_t source"
|
||||
.Fc
|
||||
.Ft "unsigned long"
|
||||
.Fo dispatch_source_get_data
|
||||
.Fa "dispatch_source_t source"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_source_merge_data
|
||||
.Fa "dispatch_source_t source"
|
||||
.Fa "unsigned long data"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fo dispatch_source_set_timer
|
||||
.Fa "dispatch_source_t source"
|
||||
.Fa "dispatch_time_t start"
|
||||
.Fa "uint64_t interval"
|
||||
.Fa "uint64_t leeway"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
Dispatch event sources may be used to monitor a variety of system objects and
|
||||
events including file descriptors, mach ports, processes, virtual filesystem
|
||||
nodes, signal delivery and timers.
|
||||
.Pp
|
||||
When a state change occurs, the dispatch source will submit its event handler
|
||||
block to its target queue.
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_source_create
|
||||
function creates a new dispatch source object that may be retained and released
|
||||
with calls to
|
||||
.Fn dispatch_retain
|
||||
and
|
||||
.Fn dispatch_release
|
||||
respectively. The
|
||||
.Fa queue
|
||||
parameter specifies the target queue of the new source object, it will
|
||||
be retained by the source object. Pass the
|
||||
.Dv DISPATCH_TARGET_QUEUE_DEFAULT
|
||||
constant to use the default target queue (the default priority global
|
||||
concurrent queue).
|
||||
.Pp
|
||||
Newly created sources are created in a suspended state. After the source has
|
||||
been configured by setting an event handler, cancellation handler, registration
|
||||
handler, context,
|
||||
etc., the source must be activated by a call to
|
||||
.Fn dispatch_resume
|
||||
before any events will be delivered.
|
||||
.Pp
|
||||
Dispatch sources may be one of the following types:
|
||||
.Bl -bullet -compact -offset indent
|
||||
.It
|
||||
DISPATCH_SOURCE_TYPE_DATA_ADD
|
||||
.It
|
||||
DISPATCH_SOURCE_TYPE_DATA_OR
|
||||
.It
|
||||
DISPATCH_SOURCE_TYPE_DATA_REPLACE
|
||||
.It
|
||||
DISPATCH_SOURCE_TYPE_MACH_SEND
|
||||
.It
|
||||
DISPATCH_SOURCE_TYPE_MACH_RECV
|
||||
.It
|
||||
DISPATCH_SOURCE_TYPE_MEMORYPRESSURE
|
||||
.It
|
||||
DISPATCH_SOURCE_TYPE_PROC
|
||||
.It
|
||||
DISPATCH_SOURCE_TYPE_READ
|
||||
.It
|
||||
DISPATCH_SOURCE_TYPE_SIGNAL
|
||||
.It
|
||||
DISPATCH_SOURCE_TYPE_TIMER
|
||||
.It
|
||||
DISPATCH_SOURCE_TYPE_VNODE
|
||||
.It
|
||||
DISPATCH_SOURCE_TYPE_WRITE
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Fa handle
|
||||
and
|
||||
.Fa mask
|
||||
arguments to
|
||||
.Fn dispatch_source_create
|
||||
and the return values of the
|
||||
.Fn dispatch_source_get_handle ,
|
||||
.Fn dispatch_source_get_mask ,
|
||||
and
|
||||
.Fn dispatch_source_get_data
|
||||
functions should be interpreted according to the type of the dispatch source.
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_source_get_handle
|
||||
function
|
||||
returns the underlying handle to the dispatch source (i.e. file descriptor,
|
||||
mach port, process identifer, etc.). The result of this function may be cast
|
||||
directly to the underlying type.
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_source_get_mask
|
||||
function
|
||||
returns the set of flags that were specified at source creation time via the
|
||||
.Fa mask
|
||||
argument.
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_source_get_data
|
||||
function returns the currently pending data for the dispatch source.
|
||||
This function should only be called from within the source's event handler.
|
||||
The result of calling this function from any other context is undefined.
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_source_merge_data
|
||||
function is intended for use with the
|
||||
.Vt DISPATCH_SOURCE_TYPE_DATA_ADD ,
|
||||
.Vt DISPATCH_SOURCE_TYPE_DATA_OR
|
||||
and
|
||||
.Vt DISPATCH_SOURCE_TYPE_DATA_REPLACE
|
||||
source types. The result of using this function with any other source type is
|
||||
undefined. Data merging is performed according to the source type:
|
||||
.Bl -tag -width "XXDISPATCH_SOURCE_TYPE_DATA_REPLACE" -compact -offset indent
|
||||
.It \(bu DISPATCH_SOURCE_TYPE_DATA_ADD
|
||||
.Vt data
|
||||
is atomically added to the source's data
|
||||
.It \(bu DISPATCH_SOURCE_TYPE_DATA_OR
|
||||
.Vt data
|
||||
is atomically bitwise ORed into the source's data
|
||||
.It \(bu DISPATCH_SOURCE_TYPE_DATA_REPLACE
|
||||
.Vt data
|
||||
atomically replaces the source's data.
|
||||
.El
|
||||
.Pp
|
||||
If the source data value resulting from the merge operation is 0, the source
|
||||
handler will not be invoked. This can happen if:
|
||||
.Bl -bullet -compact -offset indent
|
||||
.It
|
||||
the atomic addition wraps for sources of type
|
||||
.Vt DISPATCH_SOURCE_TYPE_DATA_ADD ,
|
||||
.It
|
||||
0 is merged for sources of type
|
||||
.Vt DISPATCH_SOURCE_TYPE_DATA_REPLACE .
|
||||
.El
|
||||
.Pp
|
||||
.Sh SOURCE EVENT HANDLERS
|
||||
In order to receive events from the dispatch source, an event handler should be
|
||||
specified via
|
||||
.Fn dispatch_source_set_event_handler .
|
||||
The event handler block is submitted to the source's target queue when the state
|
||||
of the underlying system handle changes, or when an event occurs. If a source
|
||||
is resumed with no event handler block set, events will be quietly ignored.
|
||||
If the event handler block is changed while the source is suspended, or from a
|
||||
block running on a serial queue that is the source's target queue, then the next
|
||||
event handler invocation will use the new block.
|
||||
.Pp
|
||||
Dispatch sources may be suspended or resumed independently of their target
|
||||
queues using
|
||||
.Fn dispatch_suspend
|
||||
and
|
||||
.Fn dispatch_resume
|
||||
on the dispatch source directly. The data describing events which occur while a
|
||||
source is suspended are coalesced and delivered once the source is resumed.
|
||||
.Pp
|
||||
The
|
||||
.Fa handler
|
||||
block
|
||||
need not be reentrant safe, as it is not resubmitted to the target
|
||||
.Fa queue
|
||||
until any prior invocation for that dispatch source has completed.
|
||||
When the handler is set, the dispatch source will perform a
|
||||
.Fn Block_copy
|
||||
on the
|
||||
.Fa handler
|
||||
block.
|
||||
.Pp
|
||||
To unset the event handler, call
|
||||
.Fn dispatch_source_set_event_handler_f
|
||||
and pass NULL as
|
||||
.Fa function .
|
||||
This unsets the event handler regardless of whether the handler
|
||||
was a function pointer or a block. Registration and cancellation handlers
|
||||
(see below) may be unset in the same way, but as noted below, a cancellation
|
||||
handler may be required.
|
||||
.Sh REGISTRATION
|
||||
When
|
||||
.Fn dispatch_resume
|
||||
is called on a suspended or newly created source, there may be a brief delay
|
||||
before the source is ready to receive events from the underlying system handle.
|
||||
During this delay, the event handler will not be invoked, and events will be
|
||||
missed.
|
||||
.Pp
|
||||
Once the dispatch source is registered with the underlying system and is ready
|
||||
to process all events its optional registration handler will be submitted to
|
||||
its target queue. This registration handler may be specified via
|
||||
.Fn dispatch_source_set_registration_handler .
|
||||
.Pp
|
||||
The event handler will not be called until the registration handler finishes.
|
||||
If the source is canceled (see below) before it is registered,
|
||||
its registration handler will not be called.
|
||||
.Pp
|
||||
.Sh CANCELLATION
|
||||
The
|
||||
.Fn dispatch_source_cancel
|
||||
function asynchronously cancels the dispatch source, preventing any further
|
||||
invocation of its event handler block. Cancellation does not interrupt a
|
||||
currently executing handler block (non-preemptive). If a source is canceled
|
||||
before the first time it is resumed, its event handler will never be called.
|
||||
(In this case, note that the source must be resumed before it can be released.)
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_source_testcancel
|
||||
function may be used to determine whether the specified source has been
|
||||
canceled. A non-zero value will be returned if the source is canceled.
|
||||
.Pp
|
||||
When a dispatch source is canceled its optional cancellation handler will be
|
||||
submitted to its target queue. The cancellation handler may be specified via
|
||||
.Fn dispatch_source_set_cancel_handler .
|
||||
This cancellation handler is invoked only once, and only as a direct consequence
|
||||
of calling
|
||||
.Fn dispatch_source_cancel .
|
||||
.Pp
|
||||
.Em Important:
|
||||
a cancellation handler is required for file descriptor and mach port based
|
||||
sources in order to safely close the descriptor or destroy the port. Closing the
|
||||
descriptor or port before the cancellation handler has run may result in a race
|
||||
condition: if a new descriptor is allocated with the same value as the recently
|
||||
closed descriptor while the source's event handler is still running, the event
|
||||
handler may read/write data to the wrong descriptor.
|
||||
.Pp
|
||||
.Sh DISPATCH SOURCE TYPES
|
||||
The following section contains a summary of supported dispatch event types and
|
||||
the interpretation of their parameters and returned data.
|
||||
.Pp
|
||||
.Vt DISPATCH_SOURCE_TYPE_DATA_ADD ,
|
||||
.Vt DISPATCH_SOURCE_TYPE_DATA_OR ,
|
||||
.Vt DISPATCH_SOURCE_TYPE_DATA_REPLACE
|
||||
.Pp
|
||||
Sources of this type allow applications to manually trigger the source's event
|
||||
handler via a call to
|
||||
.Fn dispatch_source_merge_data .
|
||||
The data will be merged with the source's pending data via an atomic add or
|
||||
atomic bitwise OR, or direct replacement (based on the source's type), and the
|
||||
event handler block will be submitted to the source's target queue. The
|
||||
.Fa data
|
||||
is application defined. These sources have no
|
||||
.Fa handle
|
||||
or
|
||||
.Fa mask
|
||||
and zero should be used.
|
||||
.Pp
|
||||
.Vt DISPATCH_SOURCE_TYPE_MACH_SEND
|
||||
.Pp
|
||||
Sources of this type monitor a mach port with a send right for state changes.
|
||||
The
|
||||
.Fa handle
|
||||
is the mach port (mach_port_t) to monitor and the
|
||||
.Fa mask
|
||||
may be:
|
||||
.Bl -tag -width "XXDISPATCH_PROC_SIGNAL" -compact -offset indent
|
||||
.It \(bu DISPATCH_MACH_SEND_DEAD
|
||||
The port's corresponding receive right has been destroyed
|
||||
.El
|
||||
.Pp
|
||||
The data returned by
|
||||
.Fn dispatch_source_get_data
|
||||
is a bitmask that indicates which of the events in the
|
||||
.Fa mask
|
||||
were observed. Note that because this source type will request notifications on
|
||||
the provided port, it should not be mixed with the use of
|
||||
.Fn mach_port_request_notification
|
||||
on the same port.
|
||||
.Pp
|
||||
.Vt DISPATCH_SOURCE_TYPE_MACH_RECV
|
||||
.Pp
|
||||
Sources of this type monitor a mach port with a receive right for state changes.
|
||||
The
|
||||
.Fa handle
|
||||
is the mach port (mach_port_t) to monitor and the
|
||||
.Fa mask
|
||||
is unused and should be zero.
|
||||
The event handler block will be submitted to the target queue when a message
|
||||
on the mach port is waiting to be received.
|
||||
.Pp
|
||||
.Vt DISPATCH_SOURCE_TYPE_MEMORYPRESSURE
|
||||
.Pp
|
||||
Sources of this type monitor the system memory pressure condition for state
|
||||
changes. The
|
||||
.Fa handle
|
||||
is unused and should be zero. The
|
||||
.Fa mask
|
||||
may be one or more of the following:
|
||||
.Bl -tag -width "XXDISPATCH_MEMORYPRESSURE_CRITICAL" -compact -offset indent
|
||||
.It \(bu DISPATCH_MEMORYPRESSURE_NORMAL
|
||||
The system memory pressure condition has returned to normal.
|
||||
.It \(bu DISPATCH_MEMORYPRESSURE_WARN
|
||||
The system memory pressure condition has changed to warning.
|
||||
.It \(bu DISPATCH_MEMORYPRESSURE_CRITICAL
|
||||
The system memory pressure condition has changed to critical.
|
||||
.El
|
||||
.Pp
|
||||
The data returned by
|
||||
.Fn dispatch_source_get_data
|
||||
indicates which of the events in the
|
||||
.Fa mask
|
||||
were observed.
|
||||
.Pp
|
||||
Elevated memory pressure is a system-wide condition that applications
|
||||
registered for this source should react to by changing their future memory use
|
||||
behavior, e.g. by reducing cache sizes of newly initiated operations until
|
||||
memory pressure returns back to normal.
|
||||
.Pp
|
||||
However, applications should
|
||||
.Em NOT
|
||||
traverse and discard existing caches for past operations when the system memory
|
||||
pressure enters an elevated state, as that is likely to trigger VM operations
|
||||
that will further aggravate system memory pressure.
|
||||
.Pp
|
||||
.Vt DISPATCH_SOURCE_TYPE_PROC
|
||||
.Pp
|
||||
Sources of this type monitor processes for state changes.
|
||||
The
|
||||
.Fa handle
|
||||
is the process identifier (pid_t) of the process to monitor and the
|
||||
.Fa mask
|
||||
may be one or more of the following:
|
||||
.Bl -tag -width "XXDISPATCH_PROC_SIGNAL" -compact -offset indent
|
||||
.It \(bu DISPATCH_PROC_EXIT
|
||||
The process has exited and is available to
|
||||
.Xr wait 2 .
|
||||
.It \(bu DISPATCH_PROC_FORK
|
||||
The process has created one or more child processes.
|
||||
.It \(bu DISPATCH_PROC_EXEC
|
||||
The process has become another executable image via a call to
|
||||
.Xr execve 2
|
||||
or
|
||||
.Xr posix_spawn 2 .
|
||||
.It \(bu DISPATCH_PROC_SIGNAL
|
||||
A signal was delivered to the process.
|
||||
.El
|
||||
.Pp
|
||||
The data returned by
|
||||
.Fn dispatch_source_get_data
|
||||
is a bitmask that indicates which of the events in the
|
||||
.Fa mask
|
||||
were observed.
|
||||
.Pp
|
||||
.Vt DISPATCH_SOURCE_TYPE_READ
|
||||
.Pp
|
||||
Sources of this type monitor file descriptors for pending data.
|
||||
The
|
||||
.Fa handle
|
||||
is the file descriptor (int) to monitor and the
|
||||
.Fa mask
|
||||
is unused and should be zero.
|
||||
.Pp
|
||||
The data returned by
|
||||
.Fn dispatch_source_get_data
|
||||
is an estimated number of bytes available to be read from the descriptor. This
|
||||
estimate should be treated as a suggested
|
||||
.Em minimum
|
||||
read buffer size. There are no guarantees that a complete read of this size
|
||||
will be performed.
|
||||
.Pp
|
||||
Users of this source type are strongly encouraged to perform non-blocking I/O
|
||||
and handle any truncated reads or error conditions that may occur. See
|
||||
.Xr fcntl 2
|
||||
for additional information about setting the
|
||||
.Vt O_NONBLOCK
|
||||
flag on a file descriptor.
|
||||
.Pp
|
||||
.Vt DISPATCH_SOURCE_TYPE_SIGNAL
|
||||
.Pp
|
||||
Sources of this type monitor signals delivered to the current process. The
|
||||
.Fa handle
|
||||
is the signal number to monitor (int) and the
|
||||
.Fa mask
|
||||
is unused and should be zero.
|
||||
.Pp
|
||||
The data returned by
|
||||
.Fn dispatch_source_get_data
|
||||
is the number of signals received since the last invocation of the event handler
|
||||
block.
|
||||
.Pp
|
||||
Unlike signal handlers specified via
|
||||
.Fn sigaction ,
|
||||
the execution of the event handler block does not interrupt the current thread
|
||||
of execution; therefore the handler block is not limited to the use of signal
|
||||
safe interfaces defined in
|
||||
.Xr sigaction 2 .
|
||||
Furthermore, multiple observers of a given signal are supported; thus allowing
|
||||
applications and libraries to cooperate safely. However, a dispatch source
|
||||
.Em does not
|
||||
install a signal handler or otherwise alter the behavior of signal delivery.
|
||||
Therefore, applications must ignore or at least catch any signal that terminates
|
||||
a process by default. For example, near the top of
|
||||
.Fn main :
|
||||
.Bd -literal -offset ident
|
||||
signal(SIGTERM, SIG_IGN);
|
||||
.Ed
|
||||
.Pp
|
||||
.Vt DISPATCH_SOURCE_TYPE_TIMER
|
||||
.Pp
|
||||
Sources of this type periodically submit the event handler block to the target
|
||||
queue. The
|
||||
.Fa handle
|
||||
argument is unused and should be zero.
|
||||
.Pp
|
||||
The data returned by
|
||||
.Fn dispatch_source_get_data
|
||||
is the number of times the timer has fired since the last invocation of the
|
||||
event handler block.
|
||||
.Pp
|
||||
The timer parameters are configured with the
|
||||
.Fn dispatch_source_set_timer
|
||||
function. Once this function returns, any pending source data accumulated for
|
||||
the previous timer parameters has been cleared; the next fire of the timer will
|
||||
occur at
|
||||
.Fa start ,
|
||||
and every
|
||||
.Fa interval
|
||||
nanoseconds thereafter until the timer source is canceled.
|
||||
.Pp
|
||||
Any fire of the timer may be delayed by the system in order to improve power
|
||||
consumption and system performance. The upper limit to the allowable delay may
|
||||
be configured with the
|
||||
.Fa leeway
|
||||
argument, the lower limit is under the control of the system.
|
||||
.Pp
|
||||
For the initial timer fire at
|
||||
.Fa start ,
|
||||
the upper limit to the allowable delay is set to
|
||||
.Fa leeway
|
||||
nanoseconds. For the subsequent timer fires at
|
||||
.Fa start
|
||||
.Li "+ N *"
|
||||
.Fa interval ,
|
||||
the upper limit is
|
||||
.Li MIN(
|
||||
.Fa leeway ,
|
||||
.Fa interval
|
||||
.Li "/ 2 )" .
|
||||
.Pp
|
||||
The lower limit to the allowable delay may vary with process state such as
|
||||
visibility of application UI. If the specified timer source was created with a
|
||||
.Fa mask
|
||||
of
|
||||
.Vt DISPATCH_TIMER_STRICT ,
|
||||
the system will make a best effort to strictly observe the provided
|
||||
.Fa leeway
|
||||
value even if it is smaller than the current lower limit. Note that a minimal
|
||||
amount of delay is to be expected even if this flag is specified.
|
||||
.Pp
|
||||
The
|
||||
.Fa start
|
||||
argument also determines which clock will be used for the timer: If
|
||||
.Fa start
|
||||
is
|
||||
.Vt DISPATCH_TIME_NOW
|
||||
or was created with
|
||||
.Xr dispatch_time 3 ,
|
||||
the timer is based on up time (which is obtained from
|
||||
.Fn mach_absolute_time
|
||||
on Apple platforms).
|
||||
If
|
||||
.Fa start
|
||||
was created with
|
||||
.Xr dispatch_walltime 3 ,
|
||||
the timer is based on
|
||||
.Xr gettimeofday 3 .
|
||||
.Pp
|
||||
.Vt DISPATCH_SOURCE_TYPE_VNODE
|
||||
.Pp
|
||||
Sources of this type monitor the virtual filesystem nodes for state changes.
|
||||
The
|
||||
.Fa handle
|
||||
is a file descriptor (int) referencing the node to monitor, and
|
||||
the
|
||||
.Fa mask
|
||||
may be one or more of the following:
|
||||
.Bl -tag -width "XXDISPATCH_VNODE_ATTRIB" -compact -offset indent
|
||||
.It \(bu DISPATCH_VNODE_DELETE
|
||||
The referenced node was removed from the filesystem namespace via
|
||||
.Xr unlink 2 .
|
||||
.It \(bu DISPATCH_VNODE_WRITE
|
||||
A write to the referenced file occurred.
|
||||
.It \(bu DISPATCH_VNODE_EXTEND
|
||||
The referenced file was extended.
|
||||
.It \(bu DISPATCH_VNODE_ATTRIB
|
||||
The metadata attributes of the referenced node have changed.
|
||||
.It \(bu DISPATCH_VNODE_LINK
|
||||
The link count on the referenced node has changed.
|
||||
.It \(bu DISPATCH_VNODE_RENAME
|
||||
The referenced node was renamed.
|
||||
.It \(bu DISPATCH_VNODE_REVOKE
|
||||
Access to the referenced node was revoked via
|
||||
.Xr revoke 2
|
||||
or the underlying fileystem was unmounted.
|
||||
.It \(bu DISPATCH_VNODE_FUNLOCK
|
||||
The referenced file was unlocked by
|
||||
.Xr flock 2
|
||||
or
|
||||
.Xr close 2 .
|
||||
.El
|
||||
.Pp
|
||||
The data returned by
|
||||
.Fn dispatch_source_get_data
|
||||
is a bitmask that indicates which of the events in the
|
||||
.Fa mask
|
||||
were observed.
|
||||
.Pp
|
||||
.Vt DISPATCH_SOURCE_TYPE_WRITE
|
||||
.Pp
|
||||
Sources of this type monitor file descriptors for available write buffer space.
|
||||
The
|
||||
.Fa handle
|
||||
is the file descriptor (int) to monitor and the
|
||||
.Fa mask
|
||||
is unused and should be zero.
|
||||
.Pp
|
||||
Users of this source type are strongly encouraged to perform non-blocking I/O
|
||||
and handle any truncated reads or error conditions that may occur. See
|
||||
.Xr fcntl 2
|
||||
for additional information about setting the
|
||||
.Vt O_NONBLOCK
|
||||
flag on a file descriptor.
|
||||
.Pp
|
||||
.Sh SEE ALSO
|
||||
.Xr dispatch 3 ,
|
||||
.Xr dispatch_object 3 ,
|
||||
.Xr dispatch_queue_create 3
|
||||
130
Telegram/ThirdParty/dispatch/man/dispatch_time.3
vendored
Normal file
130
Telegram/ThirdParty/dispatch/man/dispatch_time.3
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
.\" Copyright (c) 2008-2013 Apple Inc. All rights reserved.
|
||||
.Dd May 1, 2009
|
||||
.Dt dispatch_time 3
|
||||
.Os Darwin
|
||||
.Sh NAME
|
||||
.Nm dispatch_time ,
|
||||
.Nm dispatch_walltime
|
||||
.Nd Calculate temporal milestones
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <dispatch/dispatch.h>
|
||||
.Vt static const dispatch_time_t DISPATCH_TIME_NOW = 0ull ;
|
||||
.Vt static const dispatch_time_t DISPATCH_WALLTIME_NOW = ~1ull ;
|
||||
.Vt static const dispatch_time_t DISPATCH_TIME_FOREVER = ~0ull ;
|
||||
.Ft dispatch_time_t
|
||||
.Fo dispatch_time
|
||||
.Fa "dispatch_time_t base" "int64_t offset"
|
||||
.Fc
|
||||
.Ft dispatch_time_t
|
||||
.Fo dispatch_walltime
|
||||
.Fa "struct timespec *base" "int64_t offset"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn dispatch_time
|
||||
and
|
||||
.Fn dispatch_walltime
|
||||
functions provide a simple mechanism for expressing temporal milestones for use
|
||||
with dispatch functions that need timeouts or operate on a schedule.
|
||||
.Pp
|
||||
The
|
||||
.Fa dispatch_time_t
|
||||
type is a semi-opaque integer, with only the special values
|
||||
.Vt DISPATCH_TIME_NOW ,
|
||||
.Vt DISPATCH_WALLTIME_NOW
|
||||
and
|
||||
.Vt DISPATCH_TIME_FOREVER
|
||||
being externally defined. All other values are represented using an internal
|
||||
format that is not safe for integer arithmetic or comparison.
|
||||
The internal format is subject to change.
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_time
|
||||
function returns a milestone relative to an existing milestone after adding
|
||||
.Fa offset
|
||||
nanoseconds.
|
||||
If the
|
||||
.Fa base
|
||||
parameter maps internally to a wall clock or is
|
||||
.Vt DISPATCH_WALLTIME_NOW ,
|
||||
then the returned value is relative to the wall clock.
|
||||
Otherwise, if
|
||||
.Fa base
|
||||
is
|
||||
.Vt DISPATCH_TIME_NOW ,
|
||||
then the current time of the default host clock is used. On Apple platforms,
|
||||
the value of the default host clock is obtained from
|
||||
.Vt mach_absolute_time() .
|
||||
.Pp
|
||||
The
|
||||
.Fn dispatch_walltime
|
||||
function is useful for creating a milestone relative to a fixed point in time
|
||||
using the wall clock, as specified by the optional
|
||||
.Fa base
|
||||
parameter. If
|
||||
.Fa base
|
||||
is NULL, then the current time of the wall clock is used.
|
||||
.Vt dispatch_walltime(NULL, offset)
|
||||
is equivalent to
|
||||
.Vt dispatch_time(DISPATCH_WALLTIME_NOW, offset) .
|
||||
.Sh EDGE CONDITIONS
|
||||
The
|
||||
.Fn dispatch_time
|
||||
and
|
||||
.Fn dispatch_walltime
|
||||
functions detect overflow and underflow conditions when applying the
|
||||
.Fa offset
|
||||
parameter.
|
||||
.Pp
|
||||
Overflow causes
|
||||
.Vt DISPATCH_TIME_FOREVER
|
||||
to be returned. When
|
||||
.Fa base
|
||||
is
|
||||
.Vt DISPATCH_TIME_FOREVER ,
|
||||
then the
|
||||
.Fa offset
|
||||
parameter is ignored.
|
||||
.Pp
|
||||
Underflow causes the smallest representable value to be
|
||||
returned for a given clock.
|
||||
.Sh EXAMPLES
|
||||
Create a milestone two seconds in the future, relative to the default clock:
|
||||
.Bd -literal -offset indent
|
||||
milestone = dispatch_time(DISPATCH_TIME_NOW, 2 * NSEC_PER_SEC);
|
||||
.Ed
|
||||
.Pp
|
||||
Create a milestone two seconds in the future, in wall clock time:
|
||||
.Bd -literal -offset indent
|
||||
milestone = dispatch_time(DISPATCH_WALLTIME_NOW, 2 * NSEC_PER_SEC);
|
||||
.Ed
|
||||
.Pp
|
||||
Create a milestone for use as an infinite timeout:
|
||||
.Bd -literal -offset indent
|
||||
milestone = DISPATCH_TIME_FOREVER;
|
||||
.Ed
|
||||
.Pp
|
||||
Create a milestone on Tuesday, January 19, 2038:
|
||||
.Bd -literal -offset indent
|
||||
struct timespec ts;
|
||||
ts.tv_sec = 0x7FFFFFFF;
|
||||
ts.tv_nsec = 0;
|
||||
milestone = dispatch_walltime(&ts, 0);
|
||||
.Ed
|
||||
.Pp
|
||||
Use a negative delta to create a milestone an hour before the one above:
|
||||
.Bd -literal -offset indent
|
||||
milestone = dispatch_walltime(&ts, -60 * 60 * NSEC_PER_SEC);
|
||||
.Ed
|
||||
.Sh RETURN VALUE
|
||||
These functions return an abstract value for use with
|
||||
.Fn dispatch_after ,
|
||||
.Fn dispatch_group_wait ,
|
||||
.Fn dispatch_semaphore_wait ,
|
||||
or
|
||||
.Fn dispatch_source_set_timer .
|
||||
.Sh SEE ALSO
|
||||
.Xr dispatch 3 ,
|
||||
.Xr dispatch_after 3 ,
|
||||
.Xr dispatch_group_create 3 ,
|
||||
.Xr dispatch_semaphore_create 3
|
||||
12
Telegram/ThirdParty/dispatch/os/CMakeLists.txt
vendored
Normal file
12
Telegram/ThirdParty/dispatch/os/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
# TODO(compnerd) ensure that object_private.h voucher_activity_private.h
|
||||
# voucher_private.h are included in the source tarball
|
||||
|
||||
install(FILES
|
||||
generic_base.h
|
||||
generic_unix_base.h
|
||||
generic_win_base.h
|
||||
object.h
|
||||
DESTINATION
|
||||
"${INSTALL_OS_HEADERS_DIR}")
|
||||
|
||||
161
Telegram/ThirdParty/dispatch/os/firehose_buffer_private.h
vendored
Normal file
161
Telegram/ThirdParty/dispatch/os/firehose_buffer_private.h
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#ifndef __FIREHOSE_BUFFER_PRIVATE__
|
||||
#define __FIREHOSE_BUFFER_PRIVATE__
|
||||
|
||||
#if OS_FIREHOSE_SPI
|
||||
#ifdef KERNEL
|
||||
#include <stdint.h>
|
||||
#else
|
||||
#include <os/base.h>
|
||||
#include <os/availability.h>
|
||||
#include <os/base_private.h>
|
||||
#include <dispatch/dispatch.h>
|
||||
#endif
|
||||
|
||||
#define OS_FIREHOSE_SPI_VERSION 20180226
|
||||
|
||||
/*!
|
||||
* @group Firehose SPI
|
||||
* SPI intended for logd only
|
||||
* Layout of structs is subject to change without notice
|
||||
*/
|
||||
|
||||
#define FIREHOSE_BUFFER_LIBTRACE_HEADER_SIZE 2048ul
|
||||
#define FIREHOSE_BUFFER_KERNEL_MIN_CHUNK_COUNT 16
|
||||
#define FIREHOSE_BUFFER_KERNEL_MAX_CHUNK_COUNT 64
|
||||
|
||||
typedef struct firehose_buffer_range_s {
|
||||
uint16_t fbr_offset; // offset from the start of the buffer
|
||||
uint16_t fbr_length;
|
||||
} *firehose_buffer_range_t;
|
||||
|
||||
#ifdef KERNEL
|
||||
|
||||
typedef struct firehose_chunk_s *firehose_chunk_t;
|
||||
|
||||
// implemented by the kernel
|
||||
extern void __firehose_buffer_push_to_logd(firehose_buffer_t fb, bool for_io);
|
||||
extern void __firehose_critical_region_enter(void);
|
||||
extern void __firehose_critical_region_leave(void);
|
||||
extern void __firehose_allocate(vm_offset_t *addr, vm_size_t size);
|
||||
extern uint8_t __firehose_buffer_kernel_chunk_count;
|
||||
extern uint8_t __firehose_num_kernel_io_pages;
|
||||
|
||||
#define FIREHOSE_BUFFER_KERNEL_DEFAULT_CHUNK_COUNT FIREHOSE_BUFFER_KERNEL_MIN_CHUNK_COUNT
|
||||
#define FIREHOSE_BUFFER_KERNEL_DEFAULT_IO_PAGES 8
|
||||
|
||||
#define FIREHOSE_BUFFER_KERNEL_CHUNK_COUNT __firehose_buffer_kernel_chunk_count
|
||||
#define FIREHOSE_BUFFER_CHUNK_PREALLOCATED_COUNT (__firehose_buffer_kernel_chunk_count - 1) // the first chunk is the header
|
||||
|
||||
// exported for the kernel
|
||||
firehose_tracepoint_t
|
||||
__firehose_buffer_tracepoint_reserve(uint64_t stamp, firehose_stream_t stream,
|
||||
uint16_t pubsize, uint16_t privsize, uint8_t **privptr);
|
||||
|
||||
void
|
||||
__firehose_buffer_tracepoint_flush(firehose_tracepoint_t vat,
|
||||
firehose_tracepoint_id_u vatid);
|
||||
|
||||
firehose_buffer_t
|
||||
__firehose_buffer_create(size_t *size);
|
||||
|
||||
void
|
||||
__firehose_merge_updates(firehose_push_reply_t update);
|
||||
|
||||
int
|
||||
__firehose_kernel_configuration_valid(uint8_t chunk_count, uint8_t io_pages);
|
||||
|
||||
#else
|
||||
|
||||
#define __firehose_critical_region_enter()
|
||||
#define __firehose_critical_region_leave()
|
||||
|
||||
OS_EXPORT
|
||||
const uint32_t _firehose_spi_version;
|
||||
|
||||
OS_ALWAYS_INLINE
|
||||
static inline const uint8_t *
|
||||
_firehose_tracepoint_reader_init(firehose_chunk_t fc, const uint8_t **endptr)
|
||||
{
|
||||
const uint8_t *start = fc->fc_data;
|
||||
const uint8_t *end = fc->fc_start + fc->fc_pos.fcp_next_entry_offs;
|
||||
|
||||
if (end > fc->fc_start + FIREHOSE_CHUNK_SIZE) {
|
||||
end = start;
|
||||
}
|
||||
*endptr = end;
|
||||
return start;
|
||||
}
|
||||
|
||||
OS_ALWAYS_INLINE
|
||||
static inline firehose_tracepoint_t
|
||||
_firehose_tracepoint_reader_next(const uint8_t **ptr, const uint8_t *end)
|
||||
{
|
||||
const uint16_t ft_size = offsetof(struct firehose_tracepoint_s, ft_data);
|
||||
struct ft_unaligned_s {
|
||||
struct firehose_tracepoint_s ft;
|
||||
} __attribute__((packed, aligned(1))) *uft;
|
||||
|
||||
do {
|
||||
uft = (struct ft_unaligned_s *)*ptr;
|
||||
if (uft->ft.ft_data >= end) {
|
||||
// reached the end
|
||||
return NULL;
|
||||
}
|
||||
if (!uft->ft.ft_length) {
|
||||
// tracepoint write didn't even start
|
||||
return NULL;
|
||||
}
|
||||
if (uft->ft.ft_length > end - uft->ft.ft_data) {
|
||||
// invalid length
|
||||
return NULL;
|
||||
}
|
||||
*ptr += roundup(ft_size + uft->ft.ft_length, 8);
|
||||
// test whether write of the tracepoint was finished
|
||||
} while (os_unlikely(uft->ft.ft_id.ftid_value == 0));
|
||||
|
||||
return (firehose_tracepoint_t)uft;
|
||||
}
|
||||
|
||||
#define firehose_tracepoint_foreach(ft, fbc) \
|
||||
for (const uint8_t *end, *p = _firehose_tracepoint_reader_init(fbc, &end); \
|
||||
((ft) = _firehose_tracepoint_reader_next(&p, end)); )
|
||||
|
||||
OS_ALWAYS_INLINE
|
||||
static inline bool
|
||||
firehose_buffer_range_validate(firehose_chunk_t fc, firehose_tracepoint_t ft,
|
||||
firehose_buffer_range_t range)
|
||||
{
|
||||
if (range->fbr_offset + range->fbr_length > FIREHOSE_CHUNK_SIZE) {
|
||||
return false;
|
||||
}
|
||||
if (fc->fc_start + range->fbr_offset < ft->ft_data + ft->ft_length) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif // !KERNEL
|
||||
|
||||
#endif // OS_FIREHOSE_SPI
|
||||
|
||||
#endif // __FIREHOSE_BUFFER_PRIVATE__
|
||||
484
Telegram/ThirdParty/dispatch/os/firehose_server_private.h
vendored
Normal file
484
Telegram/ThirdParty/dispatch/os/firehose_server_private.h
vendored
Normal file
@@ -0,0 +1,484 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#ifndef __FIREHOSE_SERVER_PRIVATE__
|
||||
#define __FIREHOSE_SERVER_PRIVATE__
|
||||
|
||||
#include <os/base.h>
|
||||
#include <dispatch/dispatch.h>
|
||||
#include "firehose_buffer_private.h"
|
||||
|
||||
#if OS_FIREHOSE_SPI
|
||||
/*!
|
||||
* @group Firehose SPI
|
||||
* SPI intended for logd only
|
||||
*/
|
||||
|
||||
#pragma mark - Firehose Client
|
||||
|
||||
/*!
|
||||
* @typedef firehose_client_t
|
||||
*
|
||||
* @abstract
|
||||
* Represents a firehose client.
|
||||
*
|
||||
* @discussion
|
||||
* Firehose client objects are os_object_t's, and it's legal to retain/release
|
||||
* them with os_retain / os_release.
|
||||
*/
|
||||
OS_OBJECT_DECL_CLASS(firehose_client);
|
||||
|
||||
/*!
|
||||
* @typedef firehose_event_t
|
||||
*
|
||||
* @const FIREHOSE_EVENT_NONE
|
||||
* Never passed to callbacks, meaningful for
|
||||
* firehose_client_metadata_stream_peek.
|
||||
*
|
||||
* @const FIREHOSE_EVENT_CLIENT_CONNECTED
|
||||
* A new client has connected
|
||||
*
|
||||
* This is the first event delivered, and no event is delivered until
|
||||
* the handler of that event returns
|
||||
*
|
||||
* The `page` argument is really a firehose_client_connected_info_t. The
|
||||
* `fc_pos` argument is not meaningful.
|
||||
*
|
||||
* @const FIREHOSE_EVENT_CLIENT_DIED
|
||||
* The specified client is gone and will not flush new buffers
|
||||
*
|
||||
* This is the last event delivered, it is never called before all other
|
||||
* event handlers have returned. This event is generated even when a
|
||||
* FIREHOSE_EVENT_CLIENT_CORRUPTED event has been generated.
|
||||
*
|
||||
* @const FIREHOSE_EVENT_IO_BUFFER_RECEIVED
|
||||
* A new buffer needs to be pushed; `page` is set to that buffer, and `fc_pos`
|
||||
* to its chunk position header.
|
||||
*
|
||||
* This event can be sent concurrently wrt FIREHOSE_EVENT_MEM_BUFFER_RECEIVED
|
||||
* events.
|
||||
*
|
||||
* @const FIREHOSE_EVENT_MEM_BUFFER_RECEIVED
|
||||
* A new buffer needs to be pushed; `page` is set to that buffer, and `fc_pos`
|
||||
* to its chunk position header.
|
||||
*
|
||||
* This event can be sent concurrently wrt FIREHOSE_EVENT_IO_BUFFER_RECEIVED
|
||||
* events.
|
||||
*
|
||||
* @const FIREHOSE_EVENT_CLIENT_CORRUPTED
|
||||
* This event is received when a client is found being corrupted.
|
||||
* `page` is set to the buffer header page, and `fc_pos` is not meaningful. When
|
||||
* this event is received, logs have likely been lost for this client.
|
||||
*
|
||||
* This buffer isn't really a proper firehose buffer page, but its content may
|
||||
* be useful for debugging purposes.
|
||||
*
|
||||
* @const FIREHOSE_EVENT_CLIENT_FINALIZE
|
||||
* This event is received when a firehose client structure is about to be
|
||||
* destroyed. Only firehose_client_get_context() can ever be called with
|
||||
* the passed firehose client. The `page` argument is NULL for this event, and
|
||||
* the `fc_pos` argument is not meaningful.
|
||||
*
|
||||
* The event is sent from the context that is dropping the last refcount
|
||||
* of the client.
|
||||
*/
|
||||
OS_ENUM(firehose_event, unsigned long,
|
||||
FIREHOSE_EVENT_NONE = 0,
|
||||
FIREHOSE_EVENT_CLIENT_CONNECTED,
|
||||
FIREHOSE_EVENT_CLIENT_DIED,
|
||||
FIREHOSE_EVENT_IO_BUFFER_RECEIVED,
|
||||
FIREHOSE_EVENT_MEM_BUFFER_RECEIVED,
|
||||
FIREHOSE_EVENT_CLIENT_CORRUPTED,
|
||||
FIREHOSE_EVENT_CLIENT_FINALIZE,
|
||||
);
|
||||
|
||||
#define FIREHOSE_CLIENT_CONNECTED_INFO_VERSION 1
|
||||
|
||||
/*!
|
||||
* @typedef firehose_client_connected_info
|
||||
*
|
||||
* @abstract
|
||||
* Type of the data passed to CLIENT_CONNECTED events.
|
||||
*/
|
||||
typedef struct firehose_client_connected_info_s {
|
||||
unsigned long fcci_version;
|
||||
// version 1
|
||||
const void *fcci_data;
|
||||
size_t fcci_size;
|
||||
} *firehose_client_connected_info_t;
|
||||
|
||||
/*!
|
||||
* @function firehose_client_get_unique_pid
|
||||
*
|
||||
* @abstract
|
||||
* Returns the unique pid of the specified firehose client
|
||||
*
|
||||
* @param client
|
||||
* The specified client.
|
||||
*
|
||||
* @param pid
|
||||
* The pid for this client.
|
||||
*
|
||||
* @returns
|
||||
* The unique pid of the specified client.
|
||||
*/
|
||||
OS_NOTHROW OS_NONNULL1
|
||||
uint64_t
|
||||
firehose_client_get_unique_pid(firehose_client_t client, pid_t *pid);
|
||||
|
||||
/*!
|
||||
* @function firehose_client_get_pid_version
|
||||
*
|
||||
* @abstract
|
||||
* Returns the pid version for that client.
|
||||
*
|
||||
* @param client
|
||||
* The specified client.
|
||||
*/
|
||||
OS_NOTHROW OS_NONNULL1
|
||||
int
|
||||
firehose_client_get_pid_version(firehose_client_t client);
|
||||
|
||||
/*!
|
||||
* @function firehose_client_get_euid
|
||||
*
|
||||
* @abstract
|
||||
* Returns the EUID for that client as discovered at connect time.
|
||||
*
|
||||
* @param client
|
||||
* The specified client.
|
||||
*/
|
||||
OS_NOTHROW OS_NONNULL1
|
||||
uid_t
|
||||
firehose_client_get_euid(firehose_client_t client);
|
||||
|
||||
/*!
|
||||
* @function firehose_client_get_metadata_buffer
|
||||
*
|
||||
* @abstract
|
||||
* Returns the metadata buffer for the specified firehose client
|
||||
*
|
||||
* @param client
|
||||
* The specified client.
|
||||
*
|
||||
* @param size
|
||||
* The size of the metadata buffer.
|
||||
*
|
||||
* @returns
|
||||
* The pointer to the buffer.
|
||||
*/
|
||||
OS_NOTHROW OS_NONNULL_ALL
|
||||
void *
|
||||
firehose_client_get_metadata_buffer(firehose_client_t client, size_t *size);
|
||||
|
||||
/*!
|
||||
* @function firehose_client_get_context
|
||||
*
|
||||
* @abstract
|
||||
* Gets the context for the specified client.
|
||||
*
|
||||
* @param client
|
||||
* The specified client.
|
||||
*
|
||||
* @returns
|
||||
* The context set for the client with firehose_client_set_context
|
||||
*/
|
||||
OS_NOTHROW OS_NONNULL1
|
||||
void *
|
||||
firehose_client_get_context(firehose_client_t client);
|
||||
|
||||
/*!
|
||||
* @function firehose_client_set_strings_cached
|
||||
*
|
||||
* @abstract
|
||||
* Marks a given client as having strings cached already.
|
||||
*
|
||||
* @param client
|
||||
* The specified client.
|
||||
*/
|
||||
OS_NOTHROW OS_NONNULL1
|
||||
void
|
||||
firehose_client_set_strings_cached(firehose_client_t client);
|
||||
|
||||
/*!
|
||||
* @function firehose_client_set_context
|
||||
*
|
||||
* @abstract
|
||||
* Sets the context for the specified client.
|
||||
*
|
||||
* @discussion
|
||||
* Setting the context exchanges the context pointer, but the client must
|
||||
* ensure proper synchronization with possible getters.
|
||||
*
|
||||
* The lifetime of the context is under the control of the API user,
|
||||
* it is suggested to destroy the context when the CLIENT_DIED event is
|
||||
* received.
|
||||
*
|
||||
* @param client
|
||||
* The specified client.
|
||||
*
|
||||
* @param ctxt
|
||||
* The new context to set.
|
||||
*
|
||||
* @returns
|
||||
* The previous context set for the client.
|
||||
*/
|
||||
OS_NOTHROW OS_NONNULL1
|
||||
void *
|
||||
firehose_client_set_context(firehose_client_t client, void *ctxt);
|
||||
|
||||
/*!
|
||||
* @function firehose_client_initiate_quarantine
|
||||
*
|
||||
* @abstract
|
||||
* Starts the procedure to move the given client to the high volume quarantine
|
||||
*
|
||||
* @discussion
|
||||
* When the client is in the high volume quarantine, their firehose chunks
|
||||
* have the fcp_quarantined bit set to 1.
|
||||
*
|
||||
* @param client
|
||||
* The specified client.
|
||||
*/
|
||||
OS_NOTHROW OS_NONNULL1
|
||||
void
|
||||
firehose_client_initiate_quarantine(firehose_client_t client);
|
||||
|
||||
/*!
|
||||
* @function firehose_client_metadata_stream_peek
|
||||
*
|
||||
* @abstract
|
||||
* Peek at the metadata stream in flight buffers for a given client
|
||||
*
|
||||
* @discussion
|
||||
* This function should never be called from the context of a snapshot
|
||||
* handler.
|
||||
*
|
||||
* @param client
|
||||
* The specified client
|
||||
*
|
||||
* @param context
|
||||
* If this function is called synchronously from the handler passed to
|
||||
* firehose_server_init, then `context` should be the event being processed.
|
||||
* Else pass FIREHOSE_EVENT_NONE.
|
||||
*
|
||||
* @param peek_should_start
|
||||
* Handler that is called prior to peeking to solve the race of metadata
|
||||
* buffers not beeing processed yet at first lookup time, and being processed
|
||||
* before the peek enumeration starts.
|
||||
*
|
||||
* If the handler returns false, then the enumeration doesn't start.
|
||||
* If the race cannot happen, pass NULL.
|
||||
*
|
||||
* @param peek
|
||||
* Handler that will receive all the live metadata buffers for this process.
|
||||
* If the handler returns false, the enumeration is interrupted.
|
||||
*/
|
||||
OS_NOTHROW OS_NONNULL1 OS_NONNULL4
|
||||
void
|
||||
firehose_client_metadata_stream_peek(firehose_client_t client,
|
||||
firehose_event_t context, OS_NOESCAPE bool (^peek_should_start)(void),
|
||||
OS_NOESCAPE bool (^peek)(firehose_chunk_t fbc));
|
||||
|
||||
#pragma mark - Firehose Server
|
||||
|
||||
/*!
|
||||
* @typedef firehose_handler_t
|
||||
*
|
||||
* @abstract
|
||||
* Type of the handler block for firehose_server_init()
|
||||
*/
|
||||
typedef void (^firehose_handler_t)(firehose_client_t client,
|
||||
firehose_event_t event, firehose_chunk_t page,
|
||||
firehose_chunk_pos_u fc_pos);
|
||||
|
||||
/*!
|
||||
* @function firehose_server_init
|
||||
*
|
||||
* @abstract
|
||||
* Initializes the firehose MiG server
|
||||
*
|
||||
* @discussion
|
||||
* Initializes the firehose MiG server by boostrap registering the services
|
||||
* and creating dispatch_sources for the same.
|
||||
*/
|
||||
OS_NOTHROW
|
||||
void
|
||||
firehose_server_init(mach_port_t firehose_comm_port,
|
||||
firehose_handler_t handler);
|
||||
|
||||
/*!
|
||||
* @function firehose_server_assert_spi_version
|
||||
*
|
||||
* @abstract
|
||||
* Checks that libdispatch and firehose components all match
|
||||
*
|
||||
* @discussion
|
||||
* Will assert that all the components have the same SPI versions
|
||||
*/
|
||||
OS_NOTHROW
|
||||
void
|
||||
firehose_server_assert_spi_version(uint32_t spi_version);
|
||||
|
||||
/*!
|
||||
* @function firehose_server_has_ever_flushed_pages
|
||||
*
|
||||
* @abstract
|
||||
* Checks whether the firehose server has ever flushed any pages this boot.
|
||||
*
|
||||
* @discussion
|
||||
* Must be called after firehose_server_init() and before calling
|
||||
* firehose_server_resume().
|
||||
*/
|
||||
OS_NOTHROW
|
||||
bool
|
||||
firehose_server_has_ever_flushed_pages(void);
|
||||
|
||||
/*!
|
||||
* @function firehose_server_resume
|
||||
*
|
||||
* @abstract
|
||||
* Allows firehose events to flow
|
||||
*
|
||||
* @discussion
|
||||
* Must be called after firehose_server_init()
|
||||
*/
|
||||
OS_NOTHROW
|
||||
void
|
||||
firehose_server_resume(void);
|
||||
|
||||
/*!
|
||||
* @function firehose_server_cancel
|
||||
*
|
||||
* @abstract
|
||||
* Cancels the server, disconnects all clients, and prevents new connections.
|
||||
*/
|
||||
OS_NOTHROW
|
||||
void
|
||||
firehose_server_cancel(void);
|
||||
|
||||
/*!
|
||||
* @function firehose_server_set_logging_prefs
|
||||
*
|
||||
* @abstract
|
||||
* Publishes a new preferences buffer.
|
||||
*
|
||||
* @description
|
||||
* The server will take ownership of this buffer and will
|
||||
* call munmap() on the previous one that was stored.
|
||||
*/
|
||||
OS_NOTHROW
|
||||
void
|
||||
firehose_server_set_logging_prefs(void *pointer, size_t length,
|
||||
os_block_t block);
|
||||
|
||||
/*!
|
||||
* @typedef firehose_server_queue_t
|
||||
*
|
||||
* @abstract
|
||||
* Values to pass to firehose_server_get_queue()
|
||||
*/
|
||||
OS_ENUM(firehose_server_queue, unsigned long,
|
||||
FIREHOSE_SERVER_QUEUE_UNKNOWN,
|
||||
FIREHOSE_SERVER_QUEUE_IO,
|
||||
FIREHOSE_SERVER_QUEUE_MEMORY,
|
||||
);
|
||||
|
||||
/*!
|
||||
* @function firehose_server_copy_queue
|
||||
*
|
||||
* @abstract
|
||||
* Returns internal queues to the firehose server subsystem.
|
||||
*/
|
||||
OS_NOTHROW OS_OBJECT_RETURNS_RETAINED
|
||||
dispatch_queue_t
|
||||
firehose_server_copy_queue(firehose_server_queue_t which);
|
||||
|
||||
/*!
|
||||
* @function firehose_server_quarantined_suspend
|
||||
*
|
||||
* @abstract
|
||||
* Suspends processing of quarantined clients until
|
||||
* firehose_server_quarantined_resume() is called for the same queue.
|
||||
*
|
||||
* @discussion
|
||||
* Suspending processing of quarantined clients causes firehose_snapshot()
|
||||
* to block until the processing is enabled again.
|
||||
*
|
||||
* However if this is used to pace the processing, it is a good idea to disable
|
||||
* this pacing until the snapshot has completed.
|
||||
*
|
||||
* Similarly, quarantine suspension must be off during shutdown.
|
||||
*/
|
||||
OS_NOTHROW
|
||||
void
|
||||
firehose_server_quarantined_suspend(firehose_server_queue_t q);
|
||||
|
||||
/*!
|
||||
* @function firehose_server_quarantined_resume
|
||||
*
|
||||
* @abstract
|
||||
* Resumes processing of quarantined clients.
|
||||
*/
|
||||
OS_NOTHROW
|
||||
void
|
||||
firehose_server_quarantined_resume(firehose_server_queue_t q);
|
||||
|
||||
#pragma mark - Firehose Snapshot
|
||||
|
||||
/*!
|
||||
* @typedef firehose_snapshot_event
|
||||
*/
|
||||
OS_ENUM(firehose_snapshot_event, unsigned long,
|
||||
FIREHOSE_SNAPSHOT_EVENT_IO_START = 1,
|
||||
FIREHOSE_SNAPSHOT_EVENT_MEM_START,
|
||||
FIREHOSE_SNAPSHOT_EVENT_IO_BUFFER,
|
||||
FIREHOSE_SNAPSHOT_EVENT_MEM_BUFFER,
|
||||
FIREHOSE_SNAPSHOT_EVENT_COMPLETE,
|
||||
);
|
||||
|
||||
/*!
|
||||
* @typedef firehose_snapshot_handler_t
|
||||
*
|
||||
* @abstract
|
||||
* Type of the handler block for firehose_snapshot
|
||||
*/
|
||||
typedef void (^firehose_snapshot_handler_t)(firehose_client_t client,
|
||||
firehose_snapshot_event_t event, firehose_chunk_t page,
|
||||
firehose_chunk_pos_u fc_pos);
|
||||
|
||||
/*!
|
||||
* @function firehose_snapshot
|
||||
*
|
||||
* @abstract
|
||||
* Gather a snapshot for the current firehose state.
|
||||
*
|
||||
* @discussion
|
||||
* This function can be called several times, in which case snapshots are taken
|
||||
* one after the other. If coalescing is desired, it has to be built around this
|
||||
* call.
|
||||
*/
|
||||
OS_NOTHROW
|
||||
void
|
||||
firehose_snapshot(firehose_snapshot_handler_t handler);
|
||||
|
||||
#endif // OS_FIREHOSE_SPI
|
||||
|
||||
#endif // __FIREHOSE_SERVER_PRIVATE__
|
||||
34
Telegram/ThirdParty/dispatch/os/generic_base.h
vendored
Normal file
34
Telegram/ThirdParty/dispatch/os/generic_base.h
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2014 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#ifndef __OS_GENERIC_BASE__
|
||||
#define __OS_GENERIC_BASE__
|
||||
|
||||
#if !defined(__BEGIN_DECLS) && !defined(__END_DECLS)
|
||||
#if defined(__cplusplus)
|
||||
#define __BEGIN_DECLS extern "C" {
|
||||
#define __END_DECLS }
|
||||
#else
|
||||
#define __BEGIN_DECLS
|
||||
#define __END_DECLS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* __OS_GENERIC_BASE__ */
|
||||
130
Telegram/ThirdParty/dispatch/os/generic_unix_base.h
vendored
Normal file
130
Telegram/ThirdParty/dispatch/os/generic_unix_base.h
vendored
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
* This source file is part of the Swift.org open source project
|
||||
*
|
||||
* Copyright (c) 2015 Apple Inc. and the Swift project authors
|
||||
*
|
||||
* Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
*
|
||||
* See https://swift.org/LICENSE.txt for license information
|
||||
* See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __OS_GENERIC_UNIX_BASE__
|
||||
#define __OS_GENERIC_UNIX_BASE__
|
||||
|
||||
#include <os/generic_base.h>
|
||||
|
||||
#if __has_include(<sys/sysmacros.h>)
|
||||
#include <sys/sysmacros.h>
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__)
|
||||
#include <libutil.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
#include <sys/param.h>
|
||||
|
||||
#if __has_include(<sys/cdefs.h>)
|
||||
#include <sys/cdefs.h>
|
||||
#endif
|
||||
|
||||
#ifndef API_AVAILABLE
|
||||
#define API_AVAILABLE(...)
|
||||
#endif
|
||||
#ifndef API_DEPRECATED
|
||||
#define API_DEPRECATED(...)
|
||||
#endif
|
||||
#ifndef API_UNAVAILABLE
|
||||
#define API_UNAVAILABLE(...)
|
||||
#endif
|
||||
#ifndef API_DEPRECATED_WITH_REPLACEMENT
|
||||
#define API_DEPRECATED_WITH_REPLACEMENT(...)
|
||||
#endif
|
||||
|
||||
#if __GNUC__
|
||||
#define OS_EXPECT(x, v) __builtin_expect((x), (v))
|
||||
#define OS_UNUSED __attribute__((__unused__))
|
||||
#else
|
||||
#define OS_EXPECT(x, v) (x)
|
||||
#define OS_UNUSED
|
||||
#endif
|
||||
|
||||
#ifndef os_likely
|
||||
#define os_likely(x) OS_EXPECT(!!(x), 1)
|
||||
#endif
|
||||
#ifndef os_unlikely
|
||||
#define os_unlikely(x) OS_EXPECT(!!(x), 0)
|
||||
#endif
|
||||
|
||||
#if __has_feature(assume_nonnull)
|
||||
#define OS_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin")
|
||||
#define OS_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end")
|
||||
#else
|
||||
#define OS_ASSUME_NONNULL_BEGIN
|
||||
#define OS_ASSUME_NONNULL_END
|
||||
#endif
|
||||
|
||||
#if __has_builtin(__builtin_assume)
|
||||
#define OS_COMPILER_CAN_ASSUME(expr) __builtin_assume(expr)
|
||||
#else
|
||||
#define OS_COMPILER_CAN_ASSUME(expr) ((void)(expr))
|
||||
#endif
|
||||
|
||||
#if __has_feature(attribute_availability_swift)
|
||||
// equivalent to __SWIFT_UNAVAILABLE from Availability.h
|
||||
#define OS_SWIFT_UNAVAILABLE(_msg) \
|
||||
__attribute__((__availability__(swift, unavailable, message=_msg)))
|
||||
#else
|
||||
#define OS_SWIFT_UNAVAILABLE(_msg)
|
||||
#endif
|
||||
|
||||
#if __has_attribute(swift_private)
|
||||
# define OS_REFINED_FOR_SWIFT __attribute__((__swift_private__))
|
||||
#else
|
||||
# define OS_REFINED_FOR_SWIFT
|
||||
#endif
|
||||
|
||||
#if __has_attribute(swift_name)
|
||||
# define OS_SWIFT_NAME(_name) __attribute__((__swift_name__(#_name)))
|
||||
#else
|
||||
# define OS_SWIFT_NAME(_name)
|
||||
#endif
|
||||
|
||||
#define __OS_STRINGIFY(s) #s
|
||||
#define OS_STRINGIFY(s) __OS_STRINGIFY(s)
|
||||
#define __OS_CONCAT(x, y) x ## y
|
||||
#define OS_CONCAT(x, y) __OS_CONCAT(x, y)
|
||||
|
||||
#if __has_feature(objc_fixed_enum) || __has_extension(cxx_strong_enums)
|
||||
#define OS_ENUM(_name, _type, ...) \
|
||||
typedef enum : _type { __VA_ARGS__ } _name##_t
|
||||
#else
|
||||
#define OS_ENUM(_name, _type, ...) \
|
||||
enum { __VA_ARGS__ }; typedef _type _name##_t
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Stub out misc linking and compilation attributes
|
||||
*/
|
||||
|
||||
#ifdef OS_EXPORT
|
||||
#undef OS_EXPORT
|
||||
#endif
|
||||
#define OS_EXPORT
|
||||
|
||||
#ifdef OS_WARN_RESULT_NEEDS_RELEASE
|
||||
#undef OS_WARN_RESULT_NEEDS_RELEASE
|
||||
#endif
|
||||
|
||||
#ifdef OS_WARN_RESULT
|
||||
#undef OS_WARN_RESULT
|
||||
#endif
|
||||
#define OS_WARN_RESULT
|
||||
|
||||
#ifdef OS_NOTHROW
|
||||
#undef OS_NOTHROW
|
||||
#endif
|
||||
#define OS_NOTHROW
|
||||
|
||||
#endif /* __OS_GENERIC_UNIX_BASE__ */
|
||||
128
Telegram/ThirdParty/dispatch/os/generic_win_base.h
vendored
Normal file
128
Telegram/ThirdParty/dispatch/os/generic_win_base.h
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* This source file is part of the Swift.org open source project
|
||||
*
|
||||
* Copyright (c) 2015 Apple Inc. and the Swift project authors
|
||||
*
|
||||
* Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
*
|
||||
* See https://swift.org/LICENSE.txt for license information
|
||||
* See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __OS_GENERIC_WIN_BASE__
|
||||
#define __OS_GENERIC_WIN_BASE__
|
||||
|
||||
#include <os/generic_base.h>
|
||||
|
||||
// Unices provide `roundup` via sys/param.h
|
||||
#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
|
||||
// Unices provide `MAX` via sys/param.h
|
||||
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||
// Unices provide `MIN` via sys/param.h
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
// Unices provide `howmany` via sys/param.h
|
||||
#define howmany(x, y) (((x) + ((y) - 1)) / (y))
|
||||
|
||||
#ifndef HAVE_MODE_T
|
||||
typedef int mode_t;
|
||||
#endif
|
||||
typedef void pthread_attr_t;
|
||||
|
||||
#ifndef API_AVAILABLE
|
||||
#define API_AVAILABLE(...)
|
||||
#endif
|
||||
#ifndef API_DEPRECATED
|
||||
#define API_DEPRECATED(...)
|
||||
#endif
|
||||
#ifndef API_UNAVAILABLE
|
||||
#define API_UNAVAILABLE(...)
|
||||
#endif
|
||||
#ifndef API_DEPRECATED_WITH_REPLACEMENT
|
||||
#define API_DEPRECATED_WITH_REPLACEMENT(...)
|
||||
#endif
|
||||
|
||||
#if !defined(__has_attribute)
|
||||
#define __has_attribute(attibute) 0
|
||||
#endif
|
||||
|
||||
#if !defined(__has_builtin)
|
||||
#define __has_builtin(builtin) 0
|
||||
#endif
|
||||
|
||||
#if !defined(__has_feature)
|
||||
#define __has_feature(feature) 0
|
||||
#endif
|
||||
|
||||
#if __has_builtin(__builtin_expect)
|
||||
#define OS_EXPECT(expression, value) __builtin_expect((expression), (value))
|
||||
#else
|
||||
#define OS_EXPECT(expression, value) (expression)
|
||||
#endif
|
||||
|
||||
#if __has_attribute(__unused__)
|
||||
#define OS_UNUSED __attribute__((__unused__))
|
||||
#else
|
||||
#define OS_UNUSED
|
||||
#endif
|
||||
|
||||
#ifndef os_likely
|
||||
#define os_likely(expression) OS_EXPECT(!!(expression), 1)
|
||||
#endif
|
||||
#ifndef os_unlikely
|
||||
#define os_unlikely(expression) OS_EXPECT(!!(expression), 0)
|
||||
#endif
|
||||
|
||||
#if __has_feature(assume_nonnull)
|
||||
#define OS_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin")
|
||||
#define OS_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end")
|
||||
#else
|
||||
#define OS_ASSUME_NONNULL_BEGIN
|
||||
#define OS_ASSUME_NONNULL_END
|
||||
#endif
|
||||
|
||||
#if __has_builtin(__builtin_assume)
|
||||
#define OS_COMPILER_CAN_ASSUME(expr) __builtin_assume(expr)
|
||||
#else
|
||||
#define OS_COMPILER_CAN_ASSUME(expr) ((void)(expr))
|
||||
#endif
|
||||
|
||||
#if __has_feature(attribute_availability_swift)
|
||||
// equivalent to __SWIFT_UNAVAILABLE from Availability.h
|
||||
#define OS_SWIFT_UNAVAILABLE(msg) \
|
||||
__attribute__((__availability__(swift, unavailable, message = msg)))
|
||||
#else
|
||||
#define OS_SWIFT_UNAVAILABLE(msg)
|
||||
#endif
|
||||
|
||||
#define __OS_STRINGIFY(s) #s
|
||||
#define OS_STRINGIFY(s) __OS_STRINGIFY(s)
|
||||
|
||||
#if __has_feature(objc_fixed_enum) || __has_extension(cxx_strong_enums)
|
||||
#define OS_ENUM(name, type, ...) typedef enum : type { __VA_ARGS__ } name##_t
|
||||
#else
|
||||
#define OS_ENUM(name, type, ...) \
|
||||
enum { __VA_ARGS__ }; \
|
||||
typedef type name##_t
|
||||
#endif
|
||||
|
||||
#ifdef OS_EXPORT
|
||||
#undef OS_EXPORT
|
||||
#endif
|
||||
#define OS_EXPORT __declspec(dllexport)
|
||||
|
||||
#ifdef OS_WARN_RESULT_NEEDS_RELEASE
|
||||
#undef OS_WARN_RESULT_NEEDS_RELEASE
|
||||
#endif
|
||||
|
||||
#ifdef OS_WARN_RESULT
|
||||
#undef OS_WARN_RESULT
|
||||
#endif
|
||||
#define OS_WARN_RESULT
|
||||
|
||||
#ifdef OS_NOTHROW
|
||||
#undef OS_NOTHROW
|
||||
#endif
|
||||
#define OS_NOTHROW
|
||||
|
||||
#endif
|
||||
272
Telegram/ThirdParty/dispatch/os/object.h
vendored
Normal file
272
Telegram/ThirdParty/dispatch/os/object.h
vendored
Normal file
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2014 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#ifndef __OS_OBJECT__
|
||||
#define __OS_OBJECT__
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <Availability.h>
|
||||
#include <os/availability.h>
|
||||
#include <TargetConditionals.h>
|
||||
#include <os/base.h>
|
||||
#elif defined(_WIN32)
|
||||
#include <os/generic_win_base.h>
|
||||
#elif defined(__unix__)
|
||||
#include <os/generic_unix_base.h>
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @header
|
||||
*
|
||||
* @preprocinfo
|
||||
* By default, libSystem objects such as GCD and XPC objects are declared as
|
||||
* Objective-C types when building with an Objective-C compiler. This allows
|
||||
* them to participate in ARC, in RR management by the Blocks runtime and in
|
||||
* leaks checking by the static analyzer, and enables them to be added to Cocoa
|
||||
* collections.
|
||||
*
|
||||
* NOTE: this requires explicit cancellation of dispatch sources and xpc
|
||||
* connections whose handler blocks capture the source/connection object,
|
||||
* resp. ensuring that such captures do not form retain cycles (e.g. by
|
||||
* declaring the source as __weak).
|
||||
*
|
||||
* To opt-out of this default behavior, add -DOS_OBJECT_USE_OBJC=0 to your
|
||||
* compiler flags.
|
||||
*
|
||||
* This mode requires a platform with the modern Objective-C runtime, the
|
||||
* Objective-C GC compiler option to be disabled, and at least a Mac OS X 10.8
|
||||
* or iOS 6.0 deployment target.
|
||||
*/
|
||||
|
||||
#ifndef OS_OBJECT_HAVE_OBJC_SUPPORT
|
||||
#if !defined(__OBJC__) || defined(__OBJC_GC__)
|
||||
# define OS_OBJECT_HAVE_OBJC_SUPPORT 0
|
||||
#elif !defined(TARGET_OS_MAC) || !TARGET_OS_MAC
|
||||
# define OS_OBJECT_HAVE_OBJC_SUPPORT 0
|
||||
#elif TARGET_OS_IOS && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0
|
||||
# define OS_OBJECT_HAVE_OBJC_SUPPORT 0
|
||||
#elif TARGET_OS_MAC && !TARGET_OS_IPHONE
|
||||
# if __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_8
|
||||
# define OS_OBJECT_HAVE_OBJC_SUPPORT 0
|
||||
# elif defined(__i386__) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_12
|
||||
# define OS_OBJECT_HAVE_OBJC_SUPPORT 0
|
||||
# else
|
||||
# define OS_OBJECT_HAVE_OBJC_SUPPORT 1
|
||||
# endif
|
||||
#else
|
||||
# define OS_OBJECT_HAVE_OBJC_SUPPORT 1
|
||||
#endif
|
||||
#endif // OS_OBJECT_HAVE_OBJC_SUPPORT
|
||||
|
||||
#if OS_OBJECT_HAVE_OBJC_SUPPORT
|
||||
#if defined(__swift__) && __swift__ && !OS_OBJECT_USE_OBJC
|
||||
#define OS_OBJECT_USE_OBJC 1
|
||||
#endif
|
||||
#ifndef OS_OBJECT_USE_OBJC
|
||||
#define OS_OBJECT_USE_OBJC 1
|
||||
#endif
|
||||
#elif defined(OS_OBJECT_USE_OBJC) && OS_OBJECT_USE_OBJC
|
||||
/* Unsupported platform for OS_OBJECT_USE_OBJC=1 */
|
||||
#undef OS_OBJECT_USE_OBJC
|
||||
#define OS_OBJECT_USE_OBJC 0
|
||||
#else
|
||||
#define OS_OBJECT_USE_OBJC 0
|
||||
#endif
|
||||
|
||||
#ifndef OS_OBJECT_SWIFT3
|
||||
#if defined(SWIFT_SDK_OVERLAY_DISPATCH_EPOCH) && \
|
||||
SWIFT_SDK_OVERLAY_DISPATCH_EPOCH >= 2
|
||||
#define OS_OBJECT_SWIFT3 1
|
||||
#else
|
||||
#define OS_OBJECT_SWIFT3 0
|
||||
#endif // SWIFT_SDK_OVERLAY_DISPATCH_EPOCH >= 2
|
||||
#endif // OS_OBJECT_SWIFT3
|
||||
|
||||
#if OS_OBJECT_USE_OBJC
|
||||
#import <objc/NSObject.h>
|
||||
#if __has_attribute(objc_independent_class)
|
||||
#define OS_OBJC_INDEPENDENT_CLASS __attribute__((objc_independent_class))
|
||||
#endif // __has_attribute(objc_independent_class)
|
||||
#ifndef OS_OBJC_INDEPENDENT_CLASS
|
||||
#define OS_OBJC_INDEPENDENT_CLASS
|
||||
#endif
|
||||
#define OS_OBJECT_CLASS(name) OS_##name
|
||||
#define OS_OBJECT_DECL_PROTOCOL(name, ...) \
|
||||
@protocol OS_OBJECT_CLASS(name) __VA_ARGS__ \
|
||||
@end
|
||||
#define OS_OBJECT_CLASS_IMPLEMENTS_PROTOCOL_IMPL(name, proto) \
|
||||
@interface name () <proto> \
|
||||
@end
|
||||
#define OS_OBJECT_CLASS_IMPLEMENTS_PROTOCOL(name, proto) \
|
||||
OS_OBJECT_CLASS_IMPLEMENTS_PROTOCOL_IMPL( \
|
||||
OS_OBJECT_CLASS(name), OS_OBJECT_CLASS(proto))
|
||||
#define OS_OBJECT_DECL_IMPL(name, ...) \
|
||||
OS_OBJECT_DECL_PROTOCOL(name, __VA_ARGS__) \
|
||||
typedef NSObject<OS_OBJECT_CLASS(name)> \
|
||||
* OS_OBJC_INDEPENDENT_CLASS name##_t
|
||||
#define OS_OBJECT_DECL_BASE(name, ...) \
|
||||
@interface OS_OBJECT_CLASS(name) : __VA_ARGS__ \
|
||||
- (instancetype)init OS_SWIFT_UNAVAILABLE("Unavailable in Swift"); \
|
||||
@end
|
||||
#define OS_OBJECT_DECL_IMPL_CLASS(name, ...) \
|
||||
OS_OBJECT_DECL_BASE(name, ## __VA_ARGS__) \
|
||||
typedef OS_OBJECT_CLASS(name) \
|
||||
* OS_OBJC_INDEPENDENT_CLASS name##_t
|
||||
#define OS_OBJECT_DECL(name, ...) \
|
||||
OS_OBJECT_DECL_IMPL(name, <NSObject>)
|
||||
#define OS_OBJECT_DECL_SUBCLASS(name, super) \
|
||||
OS_OBJECT_DECL_IMPL(name, <OS_OBJECT_CLASS(super)>)
|
||||
#if __has_attribute(ns_returns_retained)
|
||||
#define OS_OBJECT_RETURNS_RETAINED __attribute__((__ns_returns_retained__))
|
||||
#else
|
||||
#define OS_OBJECT_RETURNS_RETAINED
|
||||
#endif
|
||||
#if __has_attribute(ns_consumed)
|
||||
#define OS_OBJECT_CONSUMED __attribute__((__ns_consumed__))
|
||||
#else
|
||||
#define OS_OBJECT_CONSUMED
|
||||
#endif
|
||||
#if __has_feature(objc_arc)
|
||||
#define OS_OBJECT_BRIDGE __bridge
|
||||
#define OS_WARN_RESULT_NEEDS_RELEASE
|
||||
#else
|
||||
#define OS_OBJECT_BRIDGE
|
||||
#define OS_WARN_RESULT_NEEDS_RELEASE OS_WARN_RESULT
|
||||
#endif
|
||||
#if __has_attribute(objc_runtime_visible) && \
|
||||
((defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && \
|
||||
__MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_12) || \
|
||||
(defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && \
|
||||
!defined(__TV_OS_VERSION_MIN_REQUIRED) && \
|
||||
!defined(__WATCH_OS_VERSION_MIN_REQUIRED) && \
|
||||
__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_10_0) || \
|
||||
(defined(__TV_OS_VERSION_MIN_REQUIRED) && \
|
||||
__TV_OS_VERSION_MIN_REQUIRED < __TVOS_10_0) || \
|
||||
(defined(__WATCH_OS_VERSION_MIN_REQUIRED) && \
|
||||
__WATCH_OS_VERSION_MIN_REQUIRED < __WATCHOS_3_0))
|
||||
/*
|
||||
* To provide backward deployment of ObjC objects in Swift on pre-10.12
|
||||
* SDKs, OS_object classes can be marked as OS_OBJECT_OBJC_RUNTIME_VISIBLE.
|
||||
* When compiling with a deployment target earlier than OS X 10.12 (iOS 10.0,
|
||||
* tvOS 10.0, watchOS 3.0) the Swift compiler will only refer to this type at
|
||||
* runtime (using the ObjC runtime).
|
||||
*/
|
||||
#define OS_OBJECT_OBJC_RUNTIME_VISIBLE __attribute__((objc_runtime_visible))
|
||||
#else
|
||||
#define OS_OBJECT_OBJC_RUNTIME_VISIBLE
|
||||
#endif
|
||||
#ifndef OS_OBJECT_USE_OBJC_RETAIN_RELEASE
|
||||
#if defined(__clang_analyzer__)
|
||||
#define OS_OBJECT_USE_OBJC_RETAIN_RELEASE 1
|
||||
#elif __has_feature(objc_arc) && !OS_OBJECT_SWIFT3
|
||||
#define OS_OBJECT_USE_OBJC_RETAIN_RELEASE 1
|
||||
#else
|
||||
#define OS_OBJECT_USE_OBJC_RETAIN_RELEASE 0
|
||||
#endif
|
||||
#endif
|
||||
#if OS_OBJECT_SWIFT3
|
||||
#define OS_OBJECT_DECL_SWIFT(name) \
|
||||
OS_EXPORT OS_OBJECT_OBJC_RUNTIME_VISIBLE \
|
||||
OS_OBJECT_DECL_IMPL_CLASS(name, NSObject)
|
||||
#define OS_OBJECT_DECL_SUBCLASS_SWIFT(name, super) \
|
||||
OS_EXPORT OS_OBJECT_OBJC_RUNTIME_VISIBLE \
|
||||
OS_OBJECT_DECL_IMPL_CLASS(name, OS_OBJECT_CLASS(super))
|
||||
OS_EXPORT OS_OBJECT_OBJC_RUNTIME_VISIBLE
|
||||
OS_OBJECT_DECL_BASE(object, NSObject);
|
||||
#endif // OS_OBJECT_SWIFT3
|
||||
#else
|
||||
/*! @parseOnly */
|
||||
#define OS_OBJECT_RETURNS_RETAINED
|
||||
/*! @parseOnly */
|
||||
#define OS_OBJECT_CONSUMED
|
||||
/*! @parseOnly */
|
||||
#define OS_OBJECT_BRIDGE
|
||||
/*! @parseOnly */
|
||||
#define OS_WARN_RESULT_NEEDS_RELEASE OS_WARN_RESULT
|
||||
/*! @parseOnly */
|
||||
#define OS_OBJECT_OBJC_RUNTIME_VISIBLE
|
||||
#define OS_OBJECT_USE_OBJC_RETAIN_RELEASE 0
|
||||
#endif
|
||||
|
||||
#if OS_OBJECT_SWIFT3
|
||||
#define OS_OBJECT_DECL_CLASS(name) \
|
||||
OS_OBJECT_DECL_SUBCLASS_SWIFT(name, object)
|
||||
#elif OS_OBJECT_USE_OBJC
|
||||
#define OS_OBJECT_DECL_CLASS(name) \
|
||||
OS_OBJECT_DECL(name)
|
||||
#else
|
||||
#define OS_OBJECT_DECL_CLASS(name) \
|
||||
typedef struct name##_s *name##_t
|
||||
#endif
|
||||
|
||||
#define OS_OBJECT_GLOBAL_OBJECT(type, object) ((OS_OBJECT_BRIDGE type)&(object))
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/*!
|
||||
* @function os_retain
|
||||
*
|
||||
* @abstract
|
||||
* Increment the reference count of an os_object.
|
||||
*
|
||||
* @discussion
|
||||
* On a platform with the modern Objective-C runtime this is exactly equivalent
|
||||
* to sending the object the -[retain] message.
|
||||
*
|
||||
* @param object
|
||||
* The object to retain.
|
||||
*
|
||||
* @result
|
||||
* The retained object.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
OS_EXPORT OS_SWIFT_UNAVAILABLE("Can't be used with ARC")
|
||||
void*
|
||||
os_retain(void *object);
|
||||
#if OS_OBJECT_USE_OBJC
|
||||
#undef os_retain
|
||||
#define os_retain(object) [object retain]
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @function os_release
|
||||
*
|
||||
* @abstract
|
||||
* Decrement the reference count of a os_object.
|
||||
*
|
||||
* @discussion
|
||||
* On a platform with the modern Objective-C runtime this is exactly equivalent
|
||||
* to sending the object the -[release] message.
|
||||
*
|
||||
* @param object
|
||||
* The object to release.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
OS_EXPORT
|
||||
void OS_SWIFT_UNAVAILABLE("Can't be used with ARC")
|
||||
os_release(void *object);
|
||||
#if OS_OBJECT_USE_OBJC
|
||||
#undef os_release
|
||||
#define os_release(object) [object release]
|
||||
#endif
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif
|
||||
205
Telegram/ThirdParty/dispatch/os/object_private.h
vendored
Normal file
205
Telegram/ThirdParty/dispatch/os/object_private.h
vendored
Normal file
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2012 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/*
|
||||
* IMPORTANT: This header file describes INTERNAL interfaces to libdispatch
|
||||
* which are subject to change in future releases of Mac OS X. Any applications
|
||||
* relying on these interfaces WILL break.
|
||||
*/
|
||||
|
||||
#ifndef __OS_OBJECT_PRIVATE__
|
||||
#define __OS_OBJECT_PRIVATE__
|
||||
|
||||
#include <os/object.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if __GNUC__
|
||||
#define OS_OBJECT_NOTHROW __attribute__((__nothrow__))
|
||||
#define OS_OBJECT_NONNULL __attribute__((__nonnull__))
|
||||
#define OS_OBJECT_WARN_RESULT __attribute__((__warn_unused_result__))
|
||||
#define OS_OBJECT_MALLOC __attribute__((__malloc__))
|
||||
#ifndef OS_OBJECT_EXPORT
|
||||
#define OS_OBJECT_EXPORT extern __attribute__((visibility("default")))
|
||||
#endif
|
||||
#else
|
||||
/*! @parseOnly */
|
||||
#define OS_OBJECT_NOTHROW
|
||||
/*! @parseOnly */
|
||||
#define OS_OBJECT_NONNULL
|
||||
/*! @parseOnly */
|
||||
#define OS_OBJECT_WARN_RESULT
|
||||
/*! @parseOnly */
|
||||
#define OS_OBJECT_MALLOC
|
||||
#ifndef OS_OBJECT_EXPORT
|
||||
/*! @parseOnly */
|
||||
#define OS_OBJECT_EXPORT extern
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if OS_OBJECT_USE_OBJC && __has_feature(objc_arc)
|
||||
#define _OS_OBJECT_OBJC_ARC 1
|
||||
#else
|
||||
#define _OS_OBJECT_OBJC_ARC 0
|
||||
#endif
|
||||
|
||||
#define _OS_OBJECT_GLOBAL_REFCNT INT_MAX
|
||||
|
||||
#define _OS_OBJECT_HEADER(isa, ref_cnt, xref_cnt) \
|
||||
isa; /* must be pointer-sized */ \
|
||||
int volatile ref_cnt; \
|
||||
int volatile xref_cnt
|
||||
|
||||
#if OS_OBJECT_HAVE_OBJC_SUPPORT
|
||||
#define OS_OBJECT_CLASS_SYMBOL(name) OS_##name##_class
|
||||
#if TARGET_OS_MAC && !TARGET_OS_SIMULATOR && defined(__i386__)
|
||||
#define OS_OBJECT_HAVE_OBJC1 1
|
||||
#define OS_OBJECT_HAVE_OBJC2 0
|
||||
#define OS_OBJC_CLASS_RAW_SYMBOL_NAME(name) \
|
||||
".objc_class_name_" OS_STRINGIFY(name)
|
||||
#define _OS_OBJECT_CLASS_HEADER() \
|
||||
const void *_os_obj_objc_isa
|
||||
#else
|
||||
#define OS_OBJECT_HAVE_OBJC1 0
|
||||
#define OS_OBJECT_HAVE_OBJC2 1
|
||||
#define OS_OBJC_CLASS_RAW_SYMBOL_NAME(name) "_OBJC_CLASS_$_" OS_STRINGIFY(name)
|
||||
// Must match size of compiler-generated OBJC_CLASS structure rdar://10640168
|
||||
#define _OS_OBJECT_CLASS_HEADER() \
|
||||
void *_os_obj_objc_class_t[5]
|
||||
#endif
|
||||
#define OS_OBJECT_OBJC_CLASS_DECL(name) \
|
||||
extern void *OS_OBJECT_CLASS_SYMBOL(name) \
|
||||
__asm__(OS_OBJC_CLASS_RAW_SYMBOL_NAME(OS_OBJECT_CLASS(name)))
|
||||
#else
|
||||
#define OS_OBJECT_HAVE_OBJC1 0
|
||||
#define OS_OBJECT_HAVE_OBJC2 0
|
||||
#define _OS_OBJECT_CLASS_HEADER() \
|
||||
void (*_os_obj_xref_dispose)(_os_object_t); \
|
||||
void (*_os_obj_dispose)(_os_object_t)
|
||||
#endif
|
||||
|
||||
#define OS_OBJECT_CLASS(name) OS_##name
|
||||
|
||||
#if OS_OBJECT_USE_OBJC && OS_OBJECT_SWIFT3
|
||||
@interface OS_OBJECT_CLASS(object) (OSObjectPrivate)
|
||||
- (void)_xref_dispose;
|
||||
- (void)_dispose;
|
||||
@end
|
||||
OS_OBJECT_DECL_PROTOCOL(object, <NSObject>);
|
||||
typedef OS_OBJECT_CLASS(object) *_os_object_t;
|
||||
#define _OS_OBJECT_DECL_SUBCLASS_INTERFACE(name, super) \
|
||||
@interface OS_OBJECT_CLASS(name) : OS_OBJECT_CLASS(super) \
|
||||
<OS_OBJECT_CLASS(name)> \
|
||||
@end
|
||||
#define _OS_OBJECT_DECL_PROTOCOL(name, super) \
|
||||
OS_OBJECT_DECL_PROTOCOL(name, <OS_OBJECT_CLASS(super)>)
|
||||
#define _OS_OBJECT_CLASS_IMPLEMENTS_PROTOCOL(name, super) \
|
||||
OS_OBJECT_CLASS_IMPLEMENTS_PROTOCOL(name, super)
|
||||
#elif OS_OBJECT_USE_OBJC
|
||||
API_AVAILABLE(macos(10.8), ios(6.0))
|
||||
OS_OBJECT_EXPORT
|
||||
@interface OS_OBJECT_CLASS(object) : NSObject
|
||||
- (void)_xref_dispose;
|
||||
- (void)_dispose;
|
||||
@end
|
||||
typedef OS_OBJECT_CLASS(object) *_os_object_t;
|
||||
#define _OS_OBJECT_DECL_SUBCLASS_INTERFACE(name, super) \
|
||||
@interface OS_OBJECT_CLASS(name) : OS_OBJECT_CLASS(super) \
|
||||
<OS_OBJECT_CLASS(name)> \
|
||||
@end
|
||||
#else
|
||||
#define _OS_OBJECT_DECL_SUBCLASS_INTERFACE(name, super)
|
||||
#define _OS_OBJECT_DECL_PROTOCOL(name, super)
|
||||
#define _OS_OBJECT_CLASS_IMPLEMENTS_PROTOCOL(name, super)
|
||||
typedef struct _os_object_s *_os_object_t;
|
||||
#endif
|
||||
|
||||
OS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
#if !_OS_OBJECT_OBJC_ARC
|
||||
|
||||
API_AVAILABLE(macos(10.8), ios(6.0))
|
||||
OS_OBJECT_EXPORT OS_OBJECT_MALLOC OS_OBJECT_WARN_RESULT OS_OBJECT_NOTHROW
|
||||
OS_SWIFT_UNAVAILABLE("Unavailable in Swift")
|
||||
_os_object_t
|
||||
_os_object_alloc(const void *cls, size_t size);
|
||||
|
||||
API_AVAILABLE(macos(10.8), ios(6.0))
|
||||
OS_OBJECT_EXPORT OS_OBJECT_MALLOC OS_OBJECT_WARN_RESULT OS_OBJECT_NOTHROW
|
||||
OS_SWIFT_UNAVAILABLE("Unavailable in Swift")
|
||||
_os_object_t
|
||||
_os_object_alloc_realized(const void *cls, size_t size);
|
||||
|
||||
API_AVAILABLE(macos(10.8), ios(6.0))
|
||||
OS_OBJECT_EXPORT OS_OBJECT_NONNULL OS_OBJECT_NOTHROW
|
||||
OS_SWIFT_UNAVAILABLE("Unavailable in Swift")
|
||||
void _os_object_dealloc(_os_object_t object);
|
||||
|
||||
API_AVAILABLE(macos(10.8), ios(6.0))
|
||||
OS_OBJECT_EXPORT OS_OBJECT_NONNULL OS_OBJECT_NOTHROW
|
||||
OS_SWIFT_UNAVAILABLE("Unavailable in Swift")
|
||||
_os_object_t
|
||||
_os_object_retain(_os_object_t object);
|
||||
|
||||
API_AVAILABLE(macos(10.8), ios(6.0))
|
||||
OS_OBJECT_EXPORT OS_OBJECT_NONNULL OS_OBJECT_NOTHROW
|
||||
OS_SWIFT_UNAVAILABLE("Unavailable in Swift")
|
||||
_os_object_t
|
||||
_os_object_retain_with_resurrect(_os_object_t obj);
|
||||
|
||||
API_AVAILABLE(macos(10.8), ios(6.0))
|
||||
OS_OBJECT_EXPORT OS_OBJECT_NONNULL OS_OBJECT_NOTHROW
|
||||
OS_SWIFT_UNAVAILABLE("Unavailable in Swift")
|
||||
void
|
||||
_os_object_release(_os_object_t object);
|
||||
|
||||
API_AVAILABLE(macos(10.8), ios(6.0))
|
||||
OS_OBJECT_EXPORT OS_OBJECT_NONNULL OS_OBJECT_NOTHROW
|
||||
OS_SWIFT_UNAVAILABLE("Unavailable in Swift")
|
||||
_os_object_t
|
||||
_os_object_retain_internal(_os_object_t object);
|
||||
|
||||
API_AVAILABLE(macos(10.8), ios(6.0))
|
||||
OS_OBJECT_EXPORT OS_OBJECT_NONNULL OS_OBJECT_NOTHROW
|
||||
OS_SWIFT_UNAVAILABLE("Unavailable in Swift")
|
||||
void
|
||||
_os_object_release_internal(_os_object_t object);
|
||||
|
||||
API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0))
|
||||
OS_OBJECT_EXPORT OS_OBJECT_NONNULL OS_OBJECT_NOTHROW
|
||||
OS_SWIFT_UNAVAILABLE("Unavailable in Swift")
|
||||
_os_object_t
|
||||
_os_object_retain_internal_n(_os_object_t object, uint16_t n);
|
||||
|
||||
API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0))
|
||||
OS_OBJECT_EXPORT OS_OBJECT_NONNULL OS_OBJECT_NOTHROW
|
||||
OS_SWIFT_UNAVAILABLE("Unavailable in Swift")
|
||||
void
|
||||
_os_object_release_internal_n(_os_object_t object, uint16_t n);
|
||||
|
||||
#endif // !_OS_OBJECT_OBJC_ARC
|
||||
|
||||
__END_DECLS
|
||||
|
||||
OS_ASSUME_NONNULL_END
|
||||
|
||||
#endif
|
||||
373
Telegram/ThirdParty/dispatch/os/voucher_activity_private.h
vendored
Normal file
373
Telegram/ThirdParty/dispatch/os/voucher_activity_private.h
vendored
Normal file
@@ -0,0 +1,373 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#ifndef __OS_VOUCHER_ACTIVITY_PRIVATE__
|
||||
#define __OS_VOUCHER_ACTIVITY_PRIVATE__
|
||||
|
||||
#if OS_VOUCHER_ACTIVITY_SPI
|
||||
#if __has_include(<mach/mach_time.h>)
|
||||
#include <mach/mach_time.h>
|
||||
#include <firehose/tracepoint_private.h>
|
||||
#endif
|
||||
#if __APPLE__
|
||||
#include <os/base.h>
|
||||
#include <os/availability.h>
|
||||
#endif
|
||||
#include <sys/uio.h>
|
||||
#include <os/object.h>
|
||||
#include "voucher_private.h"
|
||||
|
||||
#define OS_VOUCHER_ACTIVITY_SPI_VERSION 20161003
|
||||
|
||||
#if OS_VOUCHER_WEAK_IMPORT
|
||||
#define OS_VOUCHER_EXPORT OS_EXPORT OS_WEAK_IMPORT
|
||||
#else
|
||||
#define OS_VOUCHER_EXPORT OS_EXPORT
|
||||
#endif
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/*!
|
||||
* @const VOUCHER_CURRENT
|
||||
* Shorthand for the currently adopted voucher
|
||||
*
|
||||
* This value can only be used as an argument to functions, and is never
|
||||
* actually returned. It looks enough like a tagged pointer object that ARC
|
||||
* won't crash if this is assigned to a temporary variable.
|
||||
*/
|
||||
#define VOUCHER_CURRENT ((OS_OBJECT_BRIDGE voucher_t)(void *)~2ul)
|
||||
|
||||
/*!
|
||||
* @function voucher_get_activity_id
|
||||
*
|
||||
* @abstract
|
||||
* Returns the activity_id associated with the specified voucher at the time
|
||||
* of the call.
|
||||
*
|
||||
* @discussion
|
||||
* When the passed voucher is VOUCHER_CURRENT this returns the current
|
||||
* activity ID.
|
||||
*
|
||||
* @param voucher
|
||||
* The specified voucher.
|
||||
*
|
||||
* @param parent_id
|
||||
* An out parameter to return the parent ID of the returned activity ID.
|
||||
*
|
||||
* @result
|
||||
* The current activity identifier, if any. When 0 is returned, parent_id will
|
||||
* also always be 0.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
|
||||
OS_VOUCHER_EXPORT OS_NOTHROW
|
||||
firehose_activity_id_t
|
||||
voucher_get_activity_id(voucher_t voucher, firehose_activity_id_t *parent_id);
|
||||
|
||||
/*!
|
||||
* @function voucher_get_activity_id_and_creator
|
||||
*
|
||||
* @abstract
|
||||
* Returns the activity_id associated with the specified voucher at the time
|
||||
* of the call.
|
||||
*
|
||||
* @discussion
|
||||
* When the passed voucher is VOUCHER_CURRENT this returns the current
|
||||
* activity ID.
|
||||
*
|
||||
* @param voucher
|
||||
* The specified voucher.
|
||||
*
|
||||
* @param creator_pid
|
||||
* The unique pid of the process that created the returned activity ID if any.
|
||||
*
|
||||
* @param parent_id
|
||||
* An out parameter to return the parent ID of the returned activity ID.
|
||||
*
|
||||
* @result
|
||||
* The current activity identifier, if any. When 0 is returned, parent_id will
|
||||
* also always be 0.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
|
||||
OS_VOUCHER_EXPORT OS_NOTHROW
|
||||
firehose_activity_id_t
|
||||
voucher_get_activity_id_and_creator(voucher_t voucher, uint64_t *creator_pid,
|
||||
firehose_activity_id_t *parent_id);
|
||||
|
||||
/*!
|
||||
* @function voucher_activity_create_with_data
|
||||
*
|
||||
* @abstract
|
||||
* Creates a voucher object with a new activity identifier.
|
||||
*
|
||||
* @discussion
|
||||
* As part of voucher transport, activities are automatically propagated by the
|
||||
* system to other threads and processes (across IPC).
|
||||
*
|
||||
* When a voucher with an activity identifier is applied to a thread, work
|
||||
* on that thread is done on behalf of this activity.
|
||||
*
|
||||
* @param trace_id
|
||||
* Tracepoint identifier returned by voucher_activity_trace_id(), intended for
|
||||
* identification of the automatic tracepoint generated as part of creating the
|
||||
* new activity.
|
||||
*
|
||||
* @param base
|
||||
* The base voucher used to create the activity. If the base voucher has an
|
||||
* activity identifier, then the created activity will be parented to that one.
|
||||
* If the passed in base has no activity identifier, the activity identifier
|
||||
* will be a top-level one, on behalf of the process that created the base
|
||||
* voucher.
|
||||
*
|
||||
* If base is VOUCHER_NONE, the activity is a top-level one, on behalf of the
|
||||
* current process.
|
||||
*
|
||||
* If base is VOUCHER_CURRENT, then the activity is naturally based on the
|
||||
* one currently applied to the current thread (the one voucher_copy() would
|
||||
* return).
|
||||
*
|
||||
* @param flags
|
||||
* See voucher_activity_flag_t documentation for effect.
|
||||
*
|
||||
* @param pubdata
|
||||
* Pointer to packed buffer of tracepoint data.
|
||||
*
|
||||
* @param publen
|
||||
* Length of data at 'pubdata'.
|
||||
*
|
||||
* @result
|
||||
* A new voucher with an activity identifier.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.12.4), ios(10.3), tvos(10.2), watchos(3.2))
|
||||
OS_VOUCHER_EXPORT OS_OBJECT_RETURNS_RETAINED OS_WARN_RESULT OS_NOTHROW
|
||||
voucher_t
|
||||
voucher_activity_create_with_data(firehose_tracepoint_id_t *trace_id,
|
||||
voucher_t base, firehose_activity_flags_t flags,
|
||||
const void *pubdata, size_t publen);
|
||||
|
||||
API_DEPRECATED_WITH_REPLACEMENT("voucher_activity_create_with_data",
|
||||
macos(10.12,10.12.4), ios(10.0,10.3), tvos(10.0,10.2), watchos(3.0,3.2))
|
||||
OS_VOUCHER_EXPORT OS_OBJECT_RETURNS_RETAINED OS_WARN_RESULT OS_NOTHROW
|
||||
voucher_t
|
||||
voucher_activity_create_with_location(firehose_tracepoint_id_t *trace_id,
|
||||
voucher_t base, firehose_activity_flags_t flags, uint64_t location);
|
||||
|
||||
/*!
|
||||
* @group Voucher Activity Trace SPI
|
||||
* SPI intended for libtrace only
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @function voucher_activity_id_allocate
|
||||
*
|
||||
* @abstract
|
||||
* Allocate a new system-wide unique activity ID.
|
||||
*
|
||||
* @param flags
|
||||
* The bottom-most 8 bits of the flags will be used to generate the ID.
|
||||
* See firehose_activity_flags_t.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0))
|
||||
OS_VOUCHER_EXPORT OS_NOTHROW
|
||||
firehose_activity_id_t
|
||||
voucher_activity_id_allocate(firehose_activity_flags_t flags);
|
||||
|
||||
/*!
|
||||
* @function voucher_activity_flush
|
||||
*
|
||||
* @abstract
|
||||
* Force flushing the specified stream.
|
||||
*
|
||||
* @discussion
|
||||
* This maks all the buffers currently being written to as full, so that
|
||||
* their current content is pushed in a timely fashion.
|
||||
*
|
||||
* When this call returns, the actual flush may or may not yet have happened.
|
||||
*
|
||||
* @param stream
|
||||
* The stream to flush.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
|
||||
OS_VOUCHER_EXPORT OS_NOTHROW
|
||||
void
|
||||
voucher_activity_flush(firehose_stream_t stream);
|
||||
|
||||
/*!
|
||||
* @function voucher_activity_trace
|
||||
*
|
||||
* @abstract
|
||||
* Add a tracepoint to the specified stream.
|
||||
*
|
||||
* @param stream
|
||||
* The stream to trace this entry into.
|
||||
*
|
||||
* @param trace_id
|
||||
* Tracepoint identifier returned by voucher_activity_trace_id()
|
||||
*
|
||||
* @param timestamp
|
||||
* The mach_approximate_time()/mach_absolute_time() value for this tracepoint.
|
||||
*
|
||||
* @param pubdata
|
||||
* Pointer to packed buffer of tracepoint data.
|
||||
*
|
||||
* @param publen
|
||||
* Length of data at 'pubdata'.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
|
||||
OS_VOUCHER_EXPORT OS_NOTHROW OS_NONNULL4
|
||||
firehose_tracepoint_id_t
|
||||
voucher_activity_trace(firehose_stream_t stream,
|
||||
firehose_tracepoint_id_t trace_id, uint64_t timestamp,
|
||||
const void *pubdata, size_t publen);
|
||||
|
||||
/*!
|
||||
* @function voucher_activity_trace_v
|
||||
*
|
||||
* @abstract
|
||||
* Add a tracepoint to the specified stream, with private data.
|
||||
*
|
||||
* @param stream
|
||||
* The stream to trace this entry into.
|
||||
*
|
||||
* @param trace_id
|
||||
* Tracepoint identifier returned by voucher_activity_trace_id()
|
||||
*
|
||||
* @param timestamp
|
||||
* The mach_approximate_time()/mach_absolute_time() value for this tracepoint.
|
||||
*
|
||||
* @param iov
|
||||
* Array of `struct iovec` pointing to the data to layout.
|
||||
* The total size of this iovec must span exactly `publen + privlen` bytes.
|
||||
* The `publen` boundary must coincide with the end of an iovec (each iovec
|
||||
* must either be pure public or pure private data).
|
||||
*
|
||||
* @param publen
|
||||
* Total length of data to read from the iovec for the public data.
|
||||
*
|
||||
* @param privlen
|
||||
* Length of data to read from the iovec after the public data for the private
|
||||
* data.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.12.4), ios(10.3), tvos(10.2), watchos(3.2))
|
||||
OS_VOUCHER_EXPORT OS_NOTHROW OS_NONNULL4
|
||||
firehose_tracepoint_id_t
|
||||
voucher_activity_trace_v(firehose_stream_t stream,
|
||||
firehose_tracepoint_id_t trace_id, uint64_t timestamp,
|
||||
const struct iovec *iov, size_t publen, size_t privlen);
|
||||
|
||||
#define VOUCHER_ACTIVITY_TRACE_FLAG_UNRELIABLE 0x01
|
||||
|
||||
API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
|
||||
OS_VOUCHER_EXPORT OS_NOTHROW OS_NONNULL4
|
||||
firehose_tracepoint_id_t
|
||||
voucher_activity_trace_v_2(firehose_stream_t stream,
|
||||
firehose_tracepoint_id_t trace_id, uint64_t timestamp,
|
||||
const struct iovec *iov, size_t publen, size_t privlen, uint32_t flags);
|
||||
|
||||
typedef const struct voucher_activity_hooks_s {
|
||||
#define VOUCHER_ACTIVITY_HOOKS_VERSION 5
|
||||
long vah_version;
|
||||
mach_port_t (*vah_get_logd_port)(void);
|
||||
dispatch_mach_handler_function_t vah_debug_channel_handler;
|
||||
kern_return_t (*vah_get_reconnect_info)(mach_vm_address_t *, mach_vm_size_t *);
|
||||
void (*vah_metadata_init)(void *metadata_buffer, size_t size);
|
||||
void (*vah_quarantine_starts)(void);
|
||||
} *voucher_activity_hooks_t;
|
||||
|
||||
/*!
|
||||
* @function voucher_activity_initialize_4libtrace
|
||||
*
|
||||
* @abstract
|
||||
* Configure upcall hooks for libtrace.
|
||||
*
|
||||
* @param hooks
|
||||
* A pointer to a voucher_activity_hooks_s structure.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
|
||||
OS_VOUCHER_EXPORT OS_NOTHROW OS_NONNULL_ALL
|
||||
void
|
||||
voucher_activity_initialize_4libtrace(voucher_activity_hooks_t hooks);
|
||||
|
||||
/*!
|
||||
* @function voucher_activity_get_metadata_buffer
|
||||
*
|
||||
* @abstract
|
||||
* Return address and length of buffer in the process trace memory area
|
||||
* reserved for libtrace metadata.
|
||||
*
|
||||
* @param length
|
||||
* Pointer to size_t variable, filled with length of metadata buffer.
|
||||
*
|
||||
* @result
|
||||
* Address of metadata buffer.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
OS_VOUCHER_EXPORT OS_WARN_RESULT OS_NOTHROW OS_NONNULL_ALL
|
||||
void *
|
||||
voucher_activity_get_metadata_buffer(size_t *length);
|
||||
|
||||
/*!
|
||||
* @function voucher_activity_get_logging_preferences
|
||||
*
|
||||
* @abstract
|
||||
* Return address and length of vm_map()ed configuration data for the logging
|
||||
* subsystem.
|
||||
*
|
||||
* @discussion
|
||||
* The data must be deallocated with vm_deallocate().
|
||||
*
|
||||
* @param length
|
||||
* Pointer to size_t variable, filled with length of preferences buffer.
|
||||
*
|
||||
* @result
|
||||
* Address of preferences buffer, returns NULL on error.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0), bridgeos(3.0))
|
||||
OS_VOUCHER_EXPORT OS_WARN_RESULT OS_NOTHROW OS_NONNULL_ALL
|
||||
void *
|
||||
voucher_activity_get_logging_preferences(size_t *length);
|
||||
|
||||
/*!
|
||||
* @function voucher_activity_should_send_strings
|
||||
*
|
||||
* @abstract
|
||||
* Returns whether the client should send the strings or not.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0), bridgeos(4.0))
|
||||
OS_VOUCHER_EXPORT OS_WARN_RESULT OS_NOTHROW
|
||||
bool
|
||||
voucher_activity_should_send_strings(void);
|
||||
|
||||
/*!
|
||||
* @function voucher_get_activity_id_4dyld
|
||||
*
|
||||
* @abstract
|
||||
* Return the current voucher activity ID. Available for the dyld client stub
|
||||
* only.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
|
||||
OS_VOUCHER_EXPORT OS_WARN_RESULT OS_NOTHROW
|
||||
firehose_activity_id_t
|
||||
voucher_get_activity_id_4dyld(void);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif // OS_VOUCHER_ACTIVITY_SPI
|
||||
|
||||
#endif // __OS_VOUCHER_ACTIVITY_PRIVATE__
|
||||
641
Telegram/ThirdParty/dispatch/os/voucher_private.h
vendored
Normal file
641
Telegram/ThirdParty/dispatch/os/voucher_private.h
vendored
Normal file
@@ -0,0 +1,641 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2014 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#ifndef __OS_VOUCHER_PRIVATE__
|
||||
#define __OS_VOUCHER_PRIVATE__
|
||||
|
||||
#if __APPLE__
|
||||
#include <os/base.h>
|
||||
#include <os/availability.h>
|
||||
#endif
|
||||
#if __has_include(<mach/mach.h>)
|
||||
#include <os/object.h>
|
||||
#include <mach/mach.h>
|
||||
#endif
|
||||
#if __has_include(<bank/bank_types.h>)
|
||||
#include <bank/bank_types.h>
|
||||
#endif
|
||||
#if __has_include(<sys/persona.h>)
|
||||
#include <sys/persona.h>
|
||||
#endif
|
||||
|
||||
#ifndef __DISPATCH_BUILDING_DISPATCH__
|
||||
#include <dispatch/dispatch.h>
|
||||
#endif /* !__DISPATCH_BUILDING_DISPATCH__ */
|
||||
|
||||
#define OS_VOUCHER_SPI_VERSION 20150630
|
||||
|
||||
#if OS_VOUCHER_WEAK_IMPORT
|
||||
#define OS_VOUCHER_EXPORT OS_EXPORT OS_WEAK_IMPORT
|
||||
#else
|
||||
#define OS_VOUCHER_EXPORT OS_EXPORT
|
||||
#endif
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_BEGIN
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/*!
|
||||
* @group Voucher Transport SPI
|
||||
* SPI intended for clients that need to transport vouchers.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @typedef voucher_t
|
||||
*
|
||||
* @abstract
|
||||
* Vouchers are immutable sets of key/value attributes that can be adopted on a
|
||||
* thread in the current process or sent to another process.
|
||||
*
|
||||
* @discussion
|
||||
* Voucher objects are os_objects (c.f. <os/object.h>). They are memory-managed
|
||||
* with the os_retain()/os_release() functions or -[retain]/-[release] methods.
|
||||
*/
|
||||
OS_OBJECT_DECL_CLASS(voucher);
|
||||
|
||||
/*!
|
||||
* @const VOUCHER_NULL
|
||||
* Represents the empty base voucher with no attributes.
|
||||
*/
|
||||
#define VOUCHER_NULL ((voucher_t)0)
|
||||
/*!
|
||||
* @const VOUCHER_INVALID
|
||||
* Represents an invalid voucher
|
||||
*/
|
||||
#define VOUCHER_INVALID ((voucher_t)-1)
|
||||
|
||||
/*!
|
||||
* @function voucher_adopt
|
||||
*
|
||||
* @abstract
|
||||
* Adopt the specified voucher on the current thread and return the voucher
|
||||
* that had been adopted previously.
|
||||
*
|
||||
* @discussion
|
||||
* Adopted vouchers are automatically carried forward by the system to other
|
||||
* threads and processes (across IPC).
|
||||
*
|
||||
* Consumes a reference to the specified voucher.
|
||||
* Returns a reference to the previous voucher.
|
||||
*
|
||||
* @param voucher
|
||||
* The voucher object to adopt on the current thread.
|
||||
*
|
||||
* @result
|
||||
* The previously adopted voucher object.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
OS_VOUCHER_EXPORT OS_OBJECT_RETURNS_RETAINED OS_WARN_RESULT_NEEDS_RELEASE
|
||||
OS_NOTHROW
|
||||
voucher_t _Nullable
|
||||
voucher_adopt(voucher_t _Nullable voucher OS_OBJECT_CONSUMED);
|
||||
|
||||
/*!
|
||||
* @function voucher_copy
|
||||
*
|
||||
* @abstract
|
||||
* Returns a reference to the voucher that had been adopted previously on the
|
||||
* current thread (or carried forward by the system).
|
||||
*
|
||||
* @result
|
||||
* The currently adopted voucher object.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
OS_VOUCHER_EXPORT OS_OBJECT_RETURNS_RETAINED OS_WARN_RESULT OS_NOTHROW
|
||||
voucher_t _Nullable
|
||||
voucher_copy(void);
|
||||
|
||||
/*!
|
||||
* @function voucher_copy_without_importance
|
||||
*
|
||||
* @abstract
|
||||
* Returns a reference to a voucher object with all the properties of the
|
||||
* voucher that had been adopted previously on the current thread, but
|
||||
* without the importance properties that are frequently attached to vouchers
|
||||
* carried with IPC requests. Importance properties may elevate the scheduling
|
||||
* of threads that adopt or retain the voucher while they service the request.
|
||||
* See xpc_transaction_begin(3) for further details on importance.
|
||||
*
|
||||
* @result
|
||||
* A copy of the currently adopted voucher object, with importance removed.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
OS_VOUCHER_EXPORT OS_OBJECT_RETURNS_RETAINED OS_WARN_RESULT OS_NOTHROW
|
||||
voucher_t _Nullable
|
||||
voucher_copy_without_importance(void);
|
||||
|
||||
/*!
|
||||
* @function voucher_replace_default_voucher
|
||||
*
|
||||
* @abstract
|
||||
* Replace process attributes of default voucher (used for IPC by this process
|
||||
* when no voucher is adopted on the sending thread) with the process attributes
|
||||
* of the voucher adopted on the current thread.
|
||||
*
|
||||
* @discussion
|
||||
* This allows a daemon to indicate from the context of an incoming IPC request
|
||||
* that all future outgoing IPC from the process should be marked as acting
|
||||
* "on behalf of" the sending process of the current IPC request (as long as the
|
||||
* thread sending that outgoing IPC is not itself in the direct context of an
|
||||
* IPC request, i.e. no voucher is adopted).
|
||||
*
|
||||
* If no voucher is adopted on the current thread or the current voucher does
|
||||
* not contain any process attributes, the default voucher is reset to the
|
||||
* default process attributes for the current process.
|
||||
*
|
||||
* CAUTION: Do NOT use this SPI without contacting the Darwin Runtime team.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
OS_VOUCHER_EXPORT OS_NOTHROW
|
||||
void
|
||||
voucher_replace_default_voucher(void);
|
||||
|
||||
/*!
|
||||
* @function voucher_decrement_importance_count4CF
|
||||
*
|
||||
* @abstract
|
||||
* Decrement external importance count of the mach voucher in the specified
|
||||
* voucher object.
|
||||
*
|
||||
* @discussion
|
||||
* This is only intended for use by CoreFoundation to explicitly manage the
|
||||
* App Nap state of an application following reception of a de-nap IPC message.
|
||||
*
|
||||
* CAUTION: Do NOT use this SPI without contacting the Darwin Runtime team.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
OS_VOUCHER_EXPORT OS_NOTHROW
|
||||
void
|
||||
voucher_decrement_importance_count4CF(voucher_t _Nullable voucher);
|
||||
|
||||
/*!
|
||||
* @group Voucher dispatch block SPI
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_block_flags_t
|
||||
* SPI Flags to pass to the dispatch_block_create* functions.
|
||||
*
|
||||
* @const DISPATCH_BLOCK_NO_VOUCHER
|
||||
* Flag indicating that a dispatch block object should not be assigned a voucher
|
||||
* object. If invoked directly, the block object will be executed with the
|
||||
* voucher adopted on the calling thread. If the block object is submitted to a
|
||||
* queue, this replaces the default behavior of associating the submitted block
|
||||
* instance with the voucher adopted at the time of submission.
|
||||
* This flag is ignored if used with the dispatch_block_create_with_voucher*()
|
||||
* functions.
|
||||
*
|
||||
*/
|
||||
#define DISPATCH_BLOCK_NO_VOUCHER (0x40ul)
|
||||
|
||||
#define DISPATCH_BLOCK_IF_LAST_RESET_QUEUE_QOS_OVERRIDE (0x80ul)
|
||||
|
||||
/*!
|
||||
* @function dispatch_block_create_with_voucher
|
||||
*
|
||||
* @abstract
|
||||
* Create a new dispatch block object on the heap from an existing block and
|
||||
* the given flags, and assign it the specified voucher object.
|
||||
*
|
||||
* @discussion
|
||||
* The provided block is Block_copy'ed to the heap, it and the specified voucher
|
||||
* object are retained by the newly created dispatch block object.
|
||||
*
|
||||
* The returned dispatch block object is intended to be submitted to a dispatch
|
||||
* queue with dispatch_async() and related functions, but may also be invoked
|
||||
* directly. Both operations can be performed an arbitrary number of times but
|
||||
* only the first completed execution of a dispatch block object can be waited
|
||||
* on with dispatch_block_wait() or observed with dispatch_block_notify().
|
||||
*
|
||||
* The returned dispatch block will be executed with the specified voucher
|
||||
* adopted for the duration of the block body.
|
||||
*
|
||||
* If the returned dispatch block object is submitted to a dispatch queue, the
|
||||
* submitted block instance will be associated with the QOS class current at the
|
||||
* time of submission, unless one of the following flags assigned a specific QOS
|
||||
* class (or no QOS class) at the time of block creation:
|
||||
* - DISPATCH_BLOCK_ASSIGN_CURRENT
|
||||
* - DISPATCH_BLOCK_NO_QOS_CLASS
|
||||
* - DISPATCH_BLOCK_DETACHED
|
||||
* The QOS class the block object will be executed with also depends on the QOS
|
||||
* class assigned to the queue and which of the following flags was specified or
|
||||
* defaulted to:
|
||||
* - DISPATCH_BLOCK_INHERIT_QOS_CLASS (default for asynchronous execution)
|
||||
* - DISPATCH_BLOCK_ENFORCE_QOS_CLASS (default for synchronous execution)
|
||||
* See description of dispatch_block_flags_t for details.
|
||||
*
|
||||
* If the returned dispatch block object is submitted directly to a serial queue
|
||||
* and is configured to execute with a specific QOS class, the system will make
|
||||
* a best effort to apply the necessary QOS overrides to ensure that blocks
|
||||
* submitted earlier to the serial queue are executed at that same QOS class or
|
||||
* higher.
|
||||
*
|
||||
* @param flags
|
||||
* Configuration flags for the block object.
|
||||
* Passing a value that is not a bitwise OR of flags from dispatch_block_flags_t
|
||||
* results in NULL being returned. The DISPATCH_BLOCK_NO_VOUCHER flag is
|
||||
* ignored.
|
||||
*
|
||||
* @param voucher
|
||||
* A voucher object or NULL.
|
||||
*
|
||||
* @param block
|
||||
* The block to create the dispatch block object from.
|
||||
*
|
||||
* @result
|
||||
* The newly created dispatch block object, or NULL.
|
||||
* When not building with Objective-C ARC, must be released with a -[release]
|
||||
* message or the Block_release() function.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL3 DISPATCH_RETURNS_RETAINED_BLOCK
|
||||
DISPATCH_WARN_RESULT DISPATCH_NOTHROW
|
||||
dispatch_block_t
|
||||
dispatch_block_create_with_voucher(dispatch_block_flags_t flags,
|
||||
voucher_t _Nullable voucher, dispatch_block_t block);
|
||||
|
||||
/*!
|
||||
* @function dispatch_block_create_with_voucher_and_qos_class
|
||||
*
|
||||
* @abstract
|
||||
* Create a new dispatch block object on the heap from an existing block and
|
||||
* the given flags, and assign it the specified voucher object, QOS class and
|
||||
* relative priority.
|
||||
*
|
||||
* @discussion
|
||||
* The provided block is Block_copy'ed to the heap, it and the specified voucher
|
||||
* object are retained by the newly created dispatch block object.
|
||||
*
|
||||
* The returned dispatch block object is intended to be submitted to a dispatch
|
||||
* queue with dispatch_async() and related functions, but may also be invoked
|
||||
* directly. Both operations can be performed an arbitrary number of times but
|
||||
* only the first completed execution of a dispatch block object can be waited
|
||||
* on with dispatch_block_wait() or observed with dispatch_block_notify().
|
||||
*
|
||||
* The returned dispatch block will be executed with the specified voucher
|
||||
* adopted for the duration of the block body.
|
||||
*
|
||||
* If invoked directly, the returned dispatch block object will be executed with
|
||||
* the assigned QOS class as long as that does not result in a lower QOS class
|
||||
* than what is current on the calling thread.
|
||||
*
|
||||
* If the returned dispatch block object is submitted to a dispatch queue, the
|
||||
* QOS class it will be executed with depends on the QOS class assigned to the
|
||||
* block, the QOS class assigned to the queue and which of the following flags
|
||||
* was specified or defaulted to:
|
||||
* - DISPATCH_BLOCK_INHERIT_QOS_CLASS: default for asynchronous execution
|
||||
* - DISPATCH_BLOCK_ENFORCE_QOS_CLASS: default for synchronous execution
|
||||
* See description of dispatch_block_flags_t for details.
|
||||
*
|
||||
* If the returned dispatch block object is submitted directly to a serial queue
|
||||
* and is configured to execute with a specific QOS class, the system will make
|
||||
* a best effort to apply the necessary QOS overrides to ensure that blocks
|
||||
* submitted earlier to the serial queue are executed at that same QOS class or
|
||||
* higher.
|
||||
*
|
||||
* @param flags
|
||||
* Configuration flags for the block object.
|
||||
* Passing a value that is not a bitwise OR of flags from dispatch_block_flags_t
|
||||
* results in NULL being returned. The DISPATCH_BLOCK_NO_VOUCHER and
|
||||
* DISPATCH_BLOCK_NO_QOS flags are ignored.
|
||||
*
|
||||
* @param voucher
|
||||
* A voucher object or NULL.
|
||||
*
|
||||
* @param qos_class
|
||||
* A QOS class value:
|
||||
* - QOS_CLASS_USER_INTERACTIVE
|
||||
* - QOS_CLASS_USER_INITIATED
|
||||
* - QOS_CLASS_DEFAULT
|
||||
* - QOS_CLASS_UTILITY
|
||||
* - QOS_CLASS_BACKGROUND
|
||||
* - QOS_CLASS_UNSPECIFIED
|
||||
* Passing QOS_CLASS_UNSPECIFIED is equivalent to specifying the
|
||||
* DISPATCH_BLOCK_NO_QOS_CLASS flag. Passing any other value results in NULL
|
||||
* being returned.
|
||||
*
|
||||
* @param relative_priority
|
||||
* A relative priority within the QOS class. This value is a negative
|
||||
* offset from the maximum supported scheduler priority for the given class.
|
||||
* Passing a value greater than zero or less than QOS_MIN_RELATIVE_PRIORITY
|
||||
* results in NULL being returned.
|
||||
*
|
||||
* @param block
|
||||
* The block to create the dispatch block object from.
|
||||
*
|
||||
* @result
|
||||
* The newly created dispatch block object, or NULL.
|
||||
* When not building with Objective-C ARC, must be released with a -[release]
|
||||
* message or the Block_release() function.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL5 DISPATCH_RETURNS_RETAINED_BLOCK
|
||||
DISPATCH_WARN_RESULT DISPATCH_NOTHROW
|
||||
dispatch_block_t
|
||||
dispatch_block_create_with_voucher_and_qos_class(dispatch_block_flags_t flags,
|
||||
voucher_t _Nullable voucher, dispatch_qos_class_t qos_class,
|
||||
int relative_priority, dispatch_block_t block);
|
||||
|
||||
/*!
|
||||
* @group Voucher dispatch queue SPI
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @function dispatch_queue_create_with_accounting_override_voucher
|
||||
*
|
||||
* @abstract
|
||||
* Deprecated, do not use, will abort process if called.
|
||||
*/
|
||||
API_DEPRECATED("removed SPI", \
|
||||
macos(10.11,10.13), ios(9.0,11.0), watchos(2.0,4.0), tvos(9.0,11.0))
|
||||
DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
|
||||
DISPATCH_NOTHROW
|
||||
dispatch_queue_t
|
||||
dispatch_queue_create_with_accounting_override_voucher(
|
||||
const char *_Nullable label,
|
||||
dispatch_queue_attr_t _Nullable attr,
|
||||
voucher_t _Nullable voucher);
|
||||
|
||||
#if __has_include(<mach/mach.h>)
|
||||
/*!
|
||||
* @group Voucher Mach SPI
|
||||
* SPI intended for clients that need to interact with mach messages or mach
|
||||
* voucher ports directly.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @function voucher_create_with_mach_msg
|
||||
*
|
||||
* @abstract
|
||||
* Creates a new voucher object from a mach message carrying a mach voucher port
|
||||
*
|
||||
* @discussion
|
||||
* Ownership of the mach voucher port in the message is transfered to the new
|
||||
* voucher object and the message header mach voucher field is cleared.
|
||||
*
|
||||
* @param msg
|
||||
* The mach message to query.
|
||||
*
|
||||
* @result
|
||||
* The newly created voucher object or NULL if the message was not carrying a
|
||||
* mach voucher.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
OS_VOUCHER_EXPORT OS_OBJECT_RETURNS_RETAINED OS_WARN_RESULT OS_NOTHROW
|
||||
voucher_t _Nullable
|
||||
voucher_create_with_mach_msg(mach_msg_header_t *msg);
|
||||
|
||||
/*!
|
||||
* @function voucher_kvoucher_debug
|
||||
*
|
||||
* @abstract
|
||||
* Writes a human-readable representation of a voucher to a memory buffer.
|
||||
*
|
||||
* @discussion
|
||||
* The formatted representation of the voucher is written starting at a given
|
||||
* offset in the buffer. If the remaining space in the buffer is too small, the
|
||||
* output is truncated. Nothing is written before buf[offset] or at or beyond
|
||||
* buf[bufsize].
|
||||
*
|
||||
* @param task
|
||||
* The task port for the task that owns the voucher port.
|
||||
*
|
||||
* @param voucher
|
||||
* The voucher port name.
|
||||
*
|
||||
* @param buf
|
||||
* The buffer to which the formatted representation of the voucher should be
|
||||
* written.
|
||||
*
|
||||
* @param bufsiz
|
||||
* The size of the buffer.
|
||||
*
|
||||
* @param offset
|
||||
* The offset of the first byte in the buffer to be used for output.
|
||||
*
|
||||
* @param prefix
|
||||
* A string to be written at the start of each line of formatted output.
|
||||
* Typically used to generate leading whitespace for indentation. Use NULL if
|
||||
* no prefix is required.
|
||||
*
|
||||
* @param max_hex_data
|
||||
* The maximum number of bytes of hex data to be formatted for voucher content
|
||||
* that is not of type MACH_VOUCHER_ATTR_KEY_ATM, MACH_VOUCHER_ATTR_KEY_BANK
|
||||
* or MACH_VOUCHER_ATTR_KEY_IMPORTANCE.
|
||||
*
|
||||
* @result
|
||||
* The offset of the first byte in the buffer following the formatted voucher
|
||||
* representation.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
|
||||
OS_VOUCHER_EXPORT OS_WARN_RESULT OS_NOTHROW DISPATCH_COLD
|
||||
size_t
|
||||
voucher_kvoucher_debug(mach_port_t task, mach_port_name_t voucher, char *buf,
|
||||
size_t bufsiz, size_t offset, char * _Nullable prefix,
|
||||
size_t max_hex_data) ;
|
||||
|
||||
/*!
|
||||
* @group Voucher Persona SPI
|
||||
* SPI intended for clients that need to interact with personas.
|
||||
*/
|
||||
|
||||
struct proc_persona_info;
|
||||
|
||||
/*!
|
||||
* @function voucher_get_current_persona
|
||||
*
|
||||
* @abstract
|
||||
* Returns the persona identifier for the current thread.
|
||||
*
|
||||
* @discussion
|
||||
* Retrieve the persona identifier from the currently adopted voucher.
|
||||
*
|
||||
* If the thread has not adopted a voucher, or the current voucher does not
|
||||
* contain persona information, this function returns the persona identifier
|
||||
* of the current process.
|
||||
*
|
||||
* If the process is not running under a persona, then this returns
|
||||
* PERSONA_ID_NONE.
|
||||
*
|
||||
* @result
|
||||
* The persona identifier for the current voucher,
|
||||
* or the persona identifier of the current process
|
||||
* or PERSONA_ID_NONE
|
||||
*/
|
||||
API_AVAILABLE(macos(10.14), ios(9.2))
|
||||
OS_VOUCHER_EXPORT OS_WARN_RESULT OS_NOTHROW
|
||||
uid_t
|
||||
voucher_get_current_persona(void);
|
||||
|
||||
/*!
|
||||
* @function voucher_get_current_persona_originator_info
|
||||
*
|
||||
* @abstract
|
||||
* Retrieve the ’originator’ process persona info for the currently adopted
|
||||
* voucher.
|
||||
*
|
||||
* @discussion
|
||||
* If there is no currently adopted voucher, or no PERSONA_TOKEN attribute
|
||||
* in that voucher, this function fails.
|
||||
*
|
||||
* @param persona_info
|
||||
* The proc_persona_info structure to fill in case of success
|
||||
*
|
||||
* @result
|
||||
* 0 on success: currently adopted voucher has a PERSONA_TOKEN
|
||||
* -1 on failure: persona_info is untouched/uninitialized
|
||||
*/
|
||||
API_AVAILABLE(macos(10.14), ios(9.2))
|
||||
OS_VOUCHER_EXPORT OS_WARN_RESULT OS_NOTHROW OS_NONNULL1
|
||||
int
|
||||
voucher_get_current_persona_originator_info(
|
||||
struct proc_persona_info *persona_info);
|
||||
|
||||
/*!
|
||||
* @function voucher_get_current_persona_proximate_info
|
||||
*
|
||||
* @abstract
|
||||
* Retrieve the ’proximate’ process persona info for the currently adopted
|
||||
* voucher.
|
||||
*
|
||||
* @discussion
|
||||
* If there is no currently adopted voucher, or no PERSONA_TOKEN attribute
|
||||
* in that voucher, this function fails.
|
||||
*
|
||||
* @param persona_info
|
||||
* The proc_persona_info structure to fill in case of success
|
||||
*
|
||||
* @result
|
||||
* 0 on success: currently adopted voucher has a PERSONA_TOKEN
|
||||
* -1 on failure: persona_info is untouched/uninitialized
|
||||
*/
|
||||
API_AVAILABLE(macos(10.14), ios(9.2))
|
||||
OS_VOUCHER_EXPORT OS_WARN_RESULT OS_NOTHROW OS_NONNULL1
|
||||
int
|
||||
voucher_get_current_persona_proximate_info(
|
||||
struct proc_persona_info *persona_info);
|
||||
|
||||
/*!
|
||||
* @function voucher_copy_with_persona_mach_voucher
|
||||
*
|
||||
* @abstract
|
||||
* Creates a copy of the currently adopted voucher and replaces its
|
||||
* persona information with the one passed in the specified mach voucher
|
||||
*
|
||||
* @discussion
|
||||
* If the specified mach voucher is not one returned from
|
||||
* mach_voucher_persona_for_originator() (called on behalf
|
||||
* of the current process), this function will fail
|
||||
*
|
||||
* @param persona_mach_voucher
|
||||
* mach voucher containing the new persona information
|
||||
*
|
||||
* @result
|
||||
* On success, a copy of the current voucher with the new
|
||||
* persona information
|
||||
* On failure, VOUCHER_INVALID
|
||||
*/
|
||||
API_AVAILABLE(macos(10.14), ios(12))
|
||||
OS_VOUCHER_EXPORT OS_OBJECT_RETURNS_RETAINED OS_WARN_RESULT OS_NOTHROW
|
||||
voucher_t _Nullable
|
||||
voucher_copy_with_persona_mach_voucher(
|
||||
mach_voucher_t persona_mach_voucher);
|
||||
|
||||
/*!
|
||||
* @function mach_voucher_persona_self
|
||||
*
|
||||
* @abstract
|
||||
* Creates a mach voucher containing the persona information of the
|
||||
* current process that can be sent as a mach port descriptor in a message
|
||||
*
|
||||
* @discussion
|
||||
* The returned mach voucher has been pre-processed so that it can be sent
|
||||
* in a message
|
||||
*
|
||||
* @param persona_mach_voucher
|
||||
* If successful, a reference to the newly created mach voucher
|
||||
*
|
||||
* @result
|
||||
* KERN_SUCCESS: a mach voucher ready to be sent in a message is
|
||||
* successfully created
|
||||
* KERN_RESOURCE_SHORTAGE: mach voucher creation failed due to
|
||||
* lack of free space
|
||||
*/
|
||||
API_AVAILABLE(macos(10.14), ios(12))
|
||||
OS_VOUCHER_EXPORT OS_WARN_RESULT OS_NOTHROW OS_NONNULL1
|
||||
kern_return_t
|
||||
mach_voucher_persona_self(mach_voucher_t *persona_mach_voucher);
|
||||
|
||||
/*!
|
||||
* @function mach_voucher_persona_for_originator
|
||||
*
|
||||
* @abstract
|
||||
* Creates a mach voucher on behalf of the originator process by copying
|
||||
* the persona information from the specified mach voucher and then
|
||||
* updating the persona identifier to the specified value
|
||||
*
|
||||
* @discussion
|
||||
* Should be called by a privileged process on behalf of the originator process.
|
||||
* The newly created mach voucher should be returned to the originator in a
|
||||
* message. The originator's thread can adopt the new persona by passing
|
||||
* this mach voucher to voucher_copy_with_persona_mach_voucher().
|
||||
*
|
||||
* @param persona_id
|
||||
* The new persona identifier to be set in the mach voucher
|
||||
*
|
||||
* @param originator_persona_mach_voucher
|
||||
* A mach voucher received from the originator, where it was created using
|
||||
* mach_voucher_persona_self()
|
||||
*
|
||||
* @param originator_unique_pid
|
||||
* Unique pid of the originator process
|
||||
*
|
||||
* @param persona_mach_voucher
|
||||
* If successful, a reference to the newly created mach voucher
|
||||
*
|
||||
* @result
|
||||
* KERN_SUCCESS: a mach voucher ready to be returned to the
|
||||
* originator was successfully created
|
||||
* KERN_NO_ACCESS: process does not have privilege to carry
|
||||
* out this operation
|
||||
* KERN_INVALID_ARGUMENT: specified persona identifier is invalid
|
||||
* KERN_INVALID_CAPABILITY: originator_unique_pid does not
|
||||
* match the specified voucher originator's unique pid
|
||||
* KERN_RESOURCE_SHORTAGE: mach voucher creation failed due to
|
||||
* lack of free space
|
||||
*/
|
||||
API_AVAILABLE(macos(10.14), ios(12))
|
||||
OS_VOUCHER_EXPORT OS_WARN_RESULT OS_NOTHROW OS_NONNULL4
|
||||
kern_return_t
|
||||
mach_voucher_persona_for_originator(uid_t persona_id,
|
||||
mach_voucher_t originator_persona_mach_voucher,
|
||||
uint64_t originator_unique_pid, mach_voucher_t *persona_mach_voucher);
|
||||
|
||||
#endif // __has_include(<mach/mach.h>)
|
||||
|
||||
__END_DECLS
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_END
|
||||
|
||||
#endif // __OS_VOUCHER_PRIVATE__
|
||||
|
||||
#if OS_VOUCHER_ACTIVITY_SPI
|
||||
#include "voucher_activity_private.h"
|
||||
#endif
|
||||
21
Telegram/ThirdParty/dispatch/private/CMakeLists.txt
vendored
Normal file
21
Telegram/ThirdParty/dispatch/private/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
# TODO(compnerd) ensure that benchmark.h data_private.h introduction_private.h
|
||||
# io_private.h layout_private.h mach_private.h private.h queue_private.h
|
||||
# source_private.h are included in the source tarball
|
||||
|
||||
if (INSTALL_PRIVATE_HEADERS)
|
||||
install(FILES
|
||||
benchmark.h
|
||||
data_private.h
|
||||
introspection_private.h
|
||||
io_private.h
|
||||
layout_private.h
|
||||
mach_private.h
|
||||
private.h
|
||||
queue_private.h
|
||||
source_private.h
|
||||
time_private.h
|
||||
workloop_private.h
|
||||
DESTINATION
|
||||
"${INSTALL_DISPATCH_HEADERS_DIR}")
|
||||
endif()
|
||||
89
Telegram/ThirdParty/dispatch/private/benchmark.h
vendored
Normal file
89
Telegram/ThirdParty/dispatch/private/benchmark.h
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2009 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/*
|
||||
* IMPORTANT: This header file describes INTERNAL interfaces to libdispatch
|
||||
* which are subject to change in future releases of Mac OS X. Any applications
|
||||
* relying on these interfaces WILL break.
|
||||
*/
|
||||
|
||||
#ifndef __DISPATCH_BENCHMARK__
|
||||
#define __DISPATCH_BENCHMARK__
|
||||
|
||||
#ifndef __DISPATCH_INDIRECT__
|
||||
#error "Please #include <dispatch/private.h> instead of this file directly."
|
||||
#include <dispatch/base.h> // for HeaderDoc
|
||||
#endif
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_BEGIN
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/*!
|
||||
* @function dispatch_benchmark
|
||||
*
|
||||
* @abstract
|
||||
* Count the average number of cycles a given block takes to execute.
|
||||
*
|
||||
* @param count
|
||||
* The number of times to serially execute the given block.
|
||||
*
|
||||
* @param block
|
||||
* The block to execute.
|
||||
*
|
||||
* @result
|
||||
* The approximate number of cycles the block takes to execute.
|
||||
*
|
||||
* @discussion
|
||||
* This function is for debugging and performance analysis work. For the best
|
||||
* results, pass a high count value to dispatch_benchmark(). When benchmarking
|
||||
* concurrent code, please compare the serial version of the code against the
|
||||
* concurrent version, and compare the concurrent version on different classes
|
||||
* of hardware. Please look for inflection points with various data sets and
|
||||
* keep the following facts in mind:
|
||||
*
|
||||
* 1) Code bound by computational bandwidth may be inferred by proportional
|
||||
* changes in performance as concurrency is increased.
|
||||
* 2) Code bound by memory bandwidth may be inferred by negligible changes in
|
||||
* performance as concurrency is increased.
|
||||
* 3) Code bound by critical sections may be inferred by retrograde changes in
|
||||
* performance as concurrency is increased.
|
||||
* 3a) Intentional: locks, mutexes, and condition variables.
|
||||
* 3b) Accidental: unrelated and frequently modified data on the same
|
||||
* cache-line.
|
||||
*/
|
||||
#ifdef __BLOCKS__
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_NOTHROW
|
||||
uint64_t
|
||||
dispatch_benchmark(size_t count, dispatch_block_t block);
|
||||
#endif
|
||||
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL3 DISPATCH_NOTHROW
|
||||
uint64_t
|
||||
dispatch_benchmark_f(size_t count, void *_Nullable ctxt,
|
||||
dispatch_function_t func);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_END
|
||||
|
||||
#endif
|
||||
10
Telegram/ThirdParty/dispatch/private/darwin/module.modulemap
vendored
Normal file
10
Telegram/ThirdParty/dispatch/private/darwin/module.modulemap
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
module DispatchPrivate [system] [extern_c] {
|
||||
umbrella header "private.h"
|
||||
exclude header "mach_private.h"
|
||||
export *
|
||||
}
|
||||
|
||||
module DispatchIntrospectionPrivate [system] [extern_c] {
|
||||
header "introspection_private.h"
|
||||
export *
|
||||
}
|
||||
325
Telegram/ThirdParty/dispatch/private/data_private.h
vendored
Normal file
325
Telegram/ThirdParty/dispatch/private/data_private.h
vendored
Normal file
@@ -0,0 +1,325 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2013 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/*
|
||||
* IMPORTANT: This header file describes INTERNAL interfaces to libdispatch
|
||||
* which are subject to change in future releases of Mac OS X. Any applications
|
||||
* relying on these interfaces WILL break.
|
||||
*/
|
||||
|
||||
#ifndef __DISPATCH_DATA_PRIVATE__
|
||||
#define __DISPATCH_DATA_PRIVATE__
|
||||
|
||||
#ifndef __DISPATCH_INDIRECT__
|
||||
#error "Please #include <dispatch/dispatch.h> instead of this file directly."
|
||||
#include <dispatch/base.h> // for HeaderDoc
|
||||
#endif
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_BEGIN
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/*!
|
||||
* @const DISPATCH_DATA_DESTRUCTOR_NONE
|
||||
* @discussion The destructor for dispatch data objects that require no buffer
|
||||
* memory management. This can be used to allow a data object to efficiently
|
||||
* encapsulate buffers that should not be copied or freed by the system.
|
||||
*/
|
||||
#define DISPATCH_DATA_DESTRUCTOR_NONE (_dispatch_data_destructor_none)
|
||||
API_AVAILABLE(macos(10.8), ios(6.0))
|
||||
DISPATCH_DATA_DESTRUCTOR_TYPE_DECL(none);
|
||||
|
||||
/*!
|
||||
* @const DISPATCH_DATA_DESTRUCTOR_VM_DEALLOCATE
|
||||
* @discussion The destructor for dispatch data objects that have been created
|
||||
* from buffers that require deallocation using vm_deallocate.
|
||||
*/
|
||||
#define DISPATCH_DATA_DESTRUCTOR_VM_DEALLOCATE \
|
||||
(_dispatch_data_destructor_vm_deallocate)
|
||||
API_AVAILABLE(macos(10.8), ios(6.0)) DISPATCH_LINUX_UNAVAILABLE()
|
||||
DISPATCH_DATA_DESTRUCTOR_TYPE_DECL(vm_deallocate);
|
||||
|
||||
/*!
|
||||
* @function dispatch_data_create_f
|
||||
* Creates a dispatch data object from the given contiguous buffer of memory. If
|
||||
* a non-default destructor is provided, ownership of the buffer remains with
|
||||
* the caller (i.e. the bytes will not be copied). The last release of the data
|
||||
* object will result in the invocation of the specified destructor function on
|
||||
* specified queue to free the buffer (passed as the context parameter).
|
||||
*
|
||||
* If the DISPATCH_DATA_DESTRUCTOR_FREE destructor is provided the buffer will
|
||||
* be freed via free(3) and the queue argument ignored.
|
||||
*
|
||||
* If the DISPATCH_DATA_DESTRUCTOR_DEFAULT destructor is provided, data object
|
||||
* creation will copy the buffer into internal memory managed by the system.
|
||||
*
|
||||
* @param buffer A contiguous buffer of data.
|
||||
* @param size The size of the contiguous buffer of data.
|
||||
* @param queue The queue to which the destructor should be submitted.
|
||||
* @param destructor The destructor function responsible for freeing the
|
||||
* data buffer when it is no longer needed.
|
||||
* @result A newly created dispatch data object.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.9), ios(7.0))
|
||||
DISPATCH_EXPORT DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT DISPATCH_NOTHROW
|
||||
dispatch_data_t
|
||||
dispatch_data_create_f(const void *buffer,
|
||||
size_t size,
|
||||
dispatch_queue_t _Nullable queue,
|
||||
dispatch_function_t _Nullable destructor);
|
||||
|
||||
/*!
|
||||
* @function dispatch_data_create_alloc
|
||||
* Creates a dispatch data object representing a newly allocated memory region
|
||||
* of the given size. If a non-NULL reference to a pointer is provided, it is
|
||||
* filled with the location of the memory region.
|
||||
*
|
||||
* It is the responsibility of the application to ensure that the data object
|
||||
* becomes immutable (i.e. the returned memory region is not further modified)
|
||||
* once the dispatch data object is passed to other API.
|
||||
*
|
||||
* @param size The size of the required allocation.
|
||||
* @param buffer_ptr A pointer to a pointer variable to be filled with the
|
||||
* location of the newly allocated memory region, or NULL.
|
||||
* @result A newly created dispatch data object.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.9), ios(6.0))
|
||||
DISPATCH_EXPORT DISPATCH_RETURNS_RETAINED
|
||||
DISPATCH_WARN_RESULT DISPATCH_NOTHROW
|
||||
dispatch_data_t
|
||||
dispatch_data_create_alloc(size_t size, void *_Nullable *_Nullable buffer_ptr);
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_data_applier_function_t
|
||||
* A function to be invoked for every contiguous memory region in a data object.
|
||||
*
|
||||
* @param context Application-defined context parameter.
|
||||
* @param region A data object representing the current region.
|
||||
* @param offset The logical offset of the current region to the start
|
||||
* of the data object.
|
||||
* @param buffer The location of the memory for the current region.
|
||||
* @param size The size of the memory for the current region.
|
||||
* @result A Boolean indicating whether traversal should continue.
|
||||
*/
|
||||
typedef bool (*dispatch_data_applier_function_t)(void *_Nullable context,
|
||||
dispatch_data_t region, size_t offset, const void *buffer, size_t size);
|
||||
|
||||
/*!
|
||||
* @function dispatch_data_apply_f
|
||||
* Traverse the memory regions represented by the specified dispatch data object
|
||||
* in logical order and invoke the specified function once for every contiguous
|
||||
* memory region encountered.
|
||||
*
|
||||
* Each invocation of the function is passed a data object representing the
|
||||
* current region and its logical offset, along with the memory location and
|
||||
* extent of the region. These allow direct read access to the memory region,
|
||||
* but are only valid until the passed-in region object is released. Note that
|
||||
* the region object is released by the system when the function returns, it is
|
||||
* the responsibility of the application to retain it if the region object or
|
||||
* the associated memory location are needed after the function returns.
|
||||
*
|
||||
* @param data The data object to traverse.
|
||||
* @param context The application-defined context to pass to the function.
|
||||
* @param applier The function to be invoked for every contiguous memory
|
||||
* region in the data object.
|
||||
* @result A Boolean indicating whether traversal completed
|
||||
* successfully.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.9), ios(6.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
bool
|
||||
dispatch_data_apply_f(dispatch_data_t data, void *_Nullable context,
|
||||
dispatch_data_applier_function_t applier);
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
/*!
|
||||
* @function dispatch_data_make_memory_entry
|
||||
* Return a mach memory entry for the memory regions represented by the
|
||||
* specified dispatch data object.
|
||||
*
|
||||
* For data objects created with the DISPATCH_DATA_DESTRUCTOR_VM_DEALLOCATE
|
||||
* destructor, directly makes a memory entry from the represented region;
|
||||
* otherwise, makes a memory entry from newly allocated pages containing a copy
|
||||
* of the represented memory regions.
|
||||
*
|
||||
* @param data The data object to make a memory entry for.
|
||||
* @result A mach port for the newly made memory entry, or
|
||||
* MACH_PORT_NULL if an error occurred.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.9), ios(6.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
mach_port_t
|
||||
dispatch_data_make_memory_entry(dispatch_data_t data);
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @functiongroup Dispatch data transform SPI
|
||||
*/
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_data_format_type_t
|
||||
*
|
||||
* @abstract
|
||||
* Data formats are used to specify the input and output types of data supplied
|
||||
* to dispatch_data_create_transform.
|
||||
*/
|
||||
typedef const struct dispatch_data_format_type_s *dispatch_data_format_type_t;
|
||||
|
||||
#define DISPATCH_DATA_FORMAT_TYPE_DECL(name) \
|
||||
DISPATCH_EXPORT const struct dispatch_data_format_type_s \
|
||||
_dispatch_data_format_type_##name
|
||||
|
||||
/*!
|
||||
* @const DISPATCH_DATA_FORMAT_TYPE_NONE
|
||||
* @discussion A data format denoting that the given input or output format is,
|
||||
* or should be, comprised of raw data bytes with no given encoding.
|
||||
*/
|
||||
#define DISPATCH_DATA_FORMAT_TYPE_NONE (&_dispatch_data_format_type_none)
|
||||
API_AVAILABLE(macos(10.8), ios(6.0))
|
||||
DISPATCH_DATA_FORMAT_TYPE_DECL(none);
|
||||
|
||||
/*!
|
||||
* @const DISPATCH_DATA_FORMAT_TYPE_BASE32
|
||||
* @discussion A data format denoting that the given input or output format is,
|
||||
* or should be, encoded in Base32 (RFC 4648) format. On input, this format will
|
||||
* skip whitespace characters. Cannot be used in conjunction with UTF format
|
||||
* types.
|
||||
*/
|
||||
#define DISPATCH_DATA_FORMAT_TYPE_BASE32 (&_dispatch_data_format_type_base32)
|
||||
API_AVAILABLE(macos(10.8), ios(6.0))
|
||||
DISPATCH_DATA_FORMAT_TYPE_DECL(base32);
|
||||
|
||||
/*!
|
||||
* @const DISPATCH_DATA_FORMAT_TYPE_BASE32HEX
|
||||
* @discussion A data format denoting that the given input or output format is,
|
||||
* or should be, encoded in Base32Hex (RFC 4648) format. On input, this format
|
||||
* will skip whitespace characters. Cannot be used in conjunction with UTF
|
||||
* format types.
|
||||
*/
|
||||
#define DISPATCH_DATA_FORMAT_TYPE_BASE32HEX \
|
||||
(&_dispatch_data_format_type_base32hex)
|
||||
API_AVAILABLE(macos(10.9), ios(7.0))
|
||||
DISPATCH_DATA_FORMAT_TYPE_DECL(base32hex);
|
||||
|
||||
/*!
|
||||
* @const DISPATCH_DATA_FORMAT_TYPE_BASE64
|
||||
* @discussion A data format denoting that the given input or output format is,
|
||||
* or should be, encoded in Base64 (RFC 4648) format. On input, this format will
|
||||
* skip whitespace characters. Cannot be used in conjunction with UTF format
|
||||
* types.
|
||||
*/
|
||||
#define DISPATCH_DATA_FORMAT_TYPE_BASE64 (&_dispatch_data_format_type_base64)
|
||||
API_AVAILABLE(macos(10.8), ios(6.0))
|
||||
DISPATCH_DATA_FORMAT_TYPE_DECL(base64);
|
||||
|
||||
/*!
|
||||
* @const DISPATCH_DATA_FORMAT_TYPE_UTF8
|
||||
* @discussion A data format denoting that the given input or output format is,
|
||||
* or should be, encoded in UTF-8 format. Is only valid when used in conjunction
|
||||
* with other UTF format types.
|
||||
*/
|
||||
#define DISPATCH_DATA_FORMAT_TYPE_UTF8 (&_dispatch_data_format_type_utf8)
|
||||
API_AVAILABLE(macos(10.8), ios(6.0))
|
||||
DISPATCH_DATA_FORMAT_TYPE_DECL(utf8);
|
||||
|
||||
/*!
|
||||
* @const DISPATCH_DATA_FORMAT_TYPE_UTF16LE
|
||||
* @discussion A data format denoting that the given input or output format is,
|
||||
* or should be, encoded in UTF-16LE format. Is only valid when used in
|
||||
* conjunction with other UTF format types.
|
||||
*/
|
||||
#define DISPATCH_DATA_FORMAT_TYPE_UTF16LE (&_dispatch_data_format_type_utf16le)
|
||||
API_AVAILABLE(macos(10.8), ios(6.0))
|
||||
DISPATCH_DATA_FORMAT_TYPE_DECL(utf16le);
|
||||
|
||||
/*!
|
||||
* @const DISPATCH_DATA_FORMAT_TYPE_UTF16BE
|
||||
* @discussion A data format denoting that the given input or output format is,
|
||||
* or should be, encoded in UTF-16BE format. Is only valid when used in
|
||||
* conjunction with other UTF format types.
|
||||
*/
|
||||
#define DISPATCH_DATA_FORMAT_TYPE_UTF16BE (&_dispatch_data_format_type_utf16be)
|
||||
API_AVAILABLE(macos(10.8), ios(6.0))
|
||||
DISPATCH_DATA_FORMAT_TYPE_DECL(utf16be);
|
||||
|
||||
/*!
|
||||
* @const DISPATCH_DATA_FORMAT_TYPE_UTFANY
|
||||
* @discussion A data format denoting that dispatch_data_create_transform should
|
||||
* attempt to automatically detect the input type based on the presence of a
|
||||
* byte order mark character at the beginning of the data. In the absence of a
|
||||
* BOM, the data will be assumed to be in UTF-8 format. Only valid as an input
|
||||
* format.
|
||||
*/
|
||||
#define DISPATCH_DATA_FORMAT_TYPE_UTF_ANY (&_dispatch_data_format_type_utf_any)
|
||||
API_AVAILABLE(macos(10.8), ios(6.0))
|
||||
DISPATCH_DATA_FORMAT_TYPE_DECL(utf_any);
|
||||
|
||||
/*!
|
||||
* @function dispatch_data_create_transform
|
||||
* Returns a new dispatch data object after transforming the given data object
|
||||
* from the supplied format, into the given output format.
|
||||
*
|
||||
* @param data
|
||||
* The data object representing the region(s) of memory to transform.
|
||||
* @param input_type
|
||||
* Flags specifying the input format of the source dispatch_data_t
|
||||
*
|
||||
* @param output_type
|
||||
* Flags specifying the expected output format of the resulting transformation.
|
||||
*
|
||||
* @result
|
||||
* A newly created dispatch data object, dispatch_data_empty if no has been
|
||||
* produced, or NULL if an error occurred.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.8), ios(6.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_RETURNS_RETAINED
|
||||
DISPATCH_WARN_RESULT DISPATCH_NOTHROW
|
||||
dispatch_data_t
|
||||
dispatch_data_create_with_transform(dispatch_data_t data,
|
||||
dispatch_data_format_type_t input_type,
|
||||
dispatch_data_format_type_t output_type);
|
||||
|
||||
/*!
|
||||
* @function dispatch_data_get_flattened_bytes_4libxpc
|
||||
*
|
||||
* Similar to dispatch_data_create_map() but attaches it to the passed in
|
||||
* dispatch data.
|
||||
*
|
||||
* The returned mapping, if not NULL, has the size returned by
|
||||
* dispatch_data_get_size() for the specified object, and its lifetime is tied
|
||||
* to the one of the dispatch data itself.
|
||||
*
|
||||
* @discussion
|
||||
* This interface is reserved for XPC usage and is not considered stable ABI.
|
||||
*
|
||||
*
|
||||
* @result
|
||||
* A newly created linear mapping for this data object, may return NULL if
|
||||
* making the dispatch data contiguous failed to allocate memory.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0), bridgeos(4.0))
|
||||
const void *_Nullable
|
||||
dispatch_data_get_flattened_bytes_4libxpc(dispatch_data_t data);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_END
|
||||
|
||||
#endif // __DISPATCH_DATA_PRIVATE__
|
||||
10
Telegram/ThirdParty/dispatch/private/generic/module.modulemap
vendored
Normal file
10
Telegram/ThirdParty/dispatch/private/generic/module.modulemap
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
module DispatchPrivate [system] [extern_c] {
|
||||
umbrella header "private.h"
|
||||
exclude header "mach_private.h"
|
||||
export *
|
||||
}
|
||||
|
||||
module DispatchIntrospectionPrivate [system] [extern_c] {
|
||||
header "introspection_private.h"
|
||||
export *
|
||||
}
|
||||
871
Telegram/ThirdParty/dispatch/private/introspection_private.h
vendored
Normal file
871
Telegram/ThirdParty/dispatch/private/introspection_private.h
vendored
Normal file
@@ -0,0 +1,871 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2013 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/*
|
||||
* IMPORTANT: This header file describes INTERNAL interfaces to libdispatch
|
||||
* which are subject to change in future releases of Mac OS X. Any applications
|
||||
* relying on these interfaces WILL break.
|
||||
*/
|
||||
|
||||
#ifndef __DISPATCH_INTROSPECTION_PRIVATE__
|
||||
#define __DISPATCH_INTROSPECTION_PRIVATE__
|
||||
|
||||
/*!
|
||||
* @header
|
||||
*
|
||||
* @abstract
|
||||
* Introspection SPI for libdispatch.
|
||||
*
|
||||
* @discussion
|
||||
* This SPI is only available in the introspection version of the library,
|
||||
* loaded by running a process with the environment variable
|
||||
* DYLD_LIBRARY_PATH=/usr/lib/system/introspection
|
||||
*
|
||||
* NOTE: most of these functions are _not_ exported from the shared library,
|
||||
* the unexported functions are intended to only be called from a debugger
|
||||
* context while the rest of the process is suspended.
|
||||
*/
|
||||
|
||||
#ifndef __BEGIN_DECLS
|
||||
#if defined(__cplusplus)
|
||||
#define __BEGIN_DECLS extern "C" {
|
||||
#define __END_DECLS }
|
||||
#else
|
||||
#define __BEGIN_DECLS
|
||||
#define __END_DECLS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
#ifndef __DISPATCH_INDIRECT__
|
||||
/*
|
||||
* Typedefs of opaque types, for direct inclusion of header in lldb expressions
|
||||
*/
|
||||
typedef __typeof__(sizeof(int)) size_t;
|
||||
typedef struct _opaque_pthread_t *pthread_t;
|
||||
typedef void (*dispatch_function_t)(void *);
|
||||
typedef struct Block_layout *dispatch_block_t;
|
||||
typedef struct dispatch_continuation_s *dispatch_continuation_t;
|
||||
typedef struct dispatch_queue_s *dispatch_queue_t;
|
||||
typedef struct dispatch_source_s *dispatch_source_t;
|
||||
typedef struct dispatch_group_s *dispatch_group_t;
|
||||
typedef struct dispatch_object_s *dispatch_object_t;
|
||||
#ifndef API_AVAILABLE
|
||||
#define API_AVAILABLE(...)
|
||||
#endif
|
||||
#ifndef DISPATCH_EXPORT
|
||||
#define DISPATCH_EXPORT extern
|
||||
#endif
|
||||
#endif // __DISPATCH_INDIRECT__
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_introspection_versions_s
|
||||
*
|
||||
* @abstract
|
||||
* A structure of version and size information of introspection structures.
|
||||
*
|
||||
* @field introspection_version
|
||||
* Version of overall dispatch_introspection SPI.
|
||||
*
|
||||
* @field hooks_version
|
||||
* Version of dispatch_introspection_hooks_s structure.
|
||||
* Version 2 adds the queue_item_complete member.
|
||||
*
|
||||
* @field hooks_size
|
||||
* Size of dispatch_introspection_hooks_s structure.
|
||||
*
|
||||
* @field queue_item_version
|
||||
* Version of dispatch_introspection_queue_item_s structure.
|
||||
*
|
||||
* @field queue_item_size
|
||||
* Size of dispatch_introspection_queue_item_s structure.
|
||||
*
|
||||
* @field queue_block_version
|
||||
* Version of dispatch_introspection_queue_block_s structure.
|
||||
*
|
||||
* @field queue_block_size
|
||||
* Size of dispatch_introspection_queue_block_s structure.
|
||||
*
|
||||
* @field queue_function_version
|
||||
* Version of dispatch_introspection_queue_function_s structure.
|
||||
*
|
||||
* @field queue_function_size
|
||||
* Size of dispatch_introspection_queue_function_s structure.
|
||||
*
|
||||
* @field queue_thread_version
|
||||
* Version of dispatch_introspection_queue_thread_s structure.
|
||||
*
|
||||
* @field queue_thread_size
|
||||
* Size of dispatch_introspection_queue_thread_s structure.
|
||||
*
|
||||
* @field object_version
|
||||
* Version of dispatch_introspection_object_s structure.
|
||||
*
|
||||
* @field object_size
|
||||
* Size of dispatch_introspection_object_s structure.
|
||||
*
|
||||
* @field queue_version
|
||||
* Version of dispatch_introspection_queue_s structure.
|
||||
*
|
||||
* @field queue_size
|
||||
* Size of dispatch_introspection_queue_s structure.
|
||||
*
|
||||
* @field source_version
|
||||
* Version of dispatch_introspection_source_s structure.
|
||||
*
|
||||
* @field source_size
|
||||
* Size of dispatch_introspection_source_s structure.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.9), ios(7.0))
|
||||
DISPATCH_EXPORT const struct dispatch_introspection_versions_s {
|
||||
unsigned long introspection_version;
|
||||
unsigned long hooks_version;
|
||||
size_t hooks_size;
|
||||
unsigned long queue_item_version;
|
||||
size_t queue_item_size;
|
||||
unsigned long queue_block_version;
|
||||
size_t queue_block_size;
|
||||
unsigned long queue_function_version;
|
||||
size_t queue_function_size;
|
||||
unsigned long queue_thread_version;
|
||||
size_t queue_thread_size;
|
||||
unsigned long object_version;
|
||||
size_t object_size;
|
||||
unsigned long queue_version;
|
||||
size_t queue_size;
|
||||
unsigned long source_version;
|
||||
size_t source_size;
|
||||
} dispatch_introspection_versions;
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_introspection_queue_block_s
|
||||
*
|
||||
* @abstract
|
||||
* A structure of introspection information for a block item enqueued on a
|
||||
* dispatch queue.
|
||||
*
|
||||
* @field continuation
|
||||
* Pointer to enqueued item.
|
||||
*
|
||||
* @field target_queue
|
||||
* Target queue of item (may be different to the queue the item is currently
|
||||
* enqueued on).
|
||||
*
|
||||
* @field block
|
||||
* Block for enqueued item.
|
||||
*
|
||||
* @field block_invoke
|
||||
* Function pointer of block for enqueued item.
|
||||
*
|
||||
* @field group
|
||||
* Group containing enqueued item (may be NULL).
|
||||
*
|
||||
* @field waiter
|
||||
* Thread waiting for completion of enqueued item (NULL if sync == 0).
|
||||
*
|
||||
* @field barrier
|
||||
* Item is a barrier on the queue (all items on serial queues are barriers).
|
||||
*
|
||||
* @field sync
|
||||
* Item was enqueued by a dispatch_sync/dispatch_barrier_sync.
|
||||
*
|
||||
* @field apply
|
||||
* Item is part of a dispatch_apply.
|
||||
*/
|
||||
typedef struct dispatch_introspection_queue_block_s {
|
||||
dispatch_continuation_t continuation;
|
||||
dispatch_queue_t target_queue;
|
||||
dispatch_block_t block;
|
||||
dispatch_function_t block_invoke;
|
||||
dispatch_group_t group;
|
||||
pthread_t waiter;
|
||||
unsigned long barrier:1,
|
||||
sync:1,
|
||||
apply:1;
|
||||
} dispatch_introspection_queue_block_s;
|
||||
typedef dispatch_introspection_queue_block_s
|
||||
*dispatch_introspection_queue_block_t;
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_introspection_queue_function_s
|
||||
*
|
||||
* @abstract
|
||||
* A structure of introspection information for a function & context pointer
|
||||
* item enqueued on a dispatch queue.
|
||||
*
|
||||
* @field continuation
|
||||
* Pointer to enqueued item.
|
||||
*
|
||||
* @field target_queue
|
||||
* Target queue of item (may be different to the queue the item is currently
|
||||
* enqueued on).
|
||||
*
|
||||
* @field context
|
||||
* Context in enqueued item.
|
||||
*
|
||||
* @field block_invoke
|
||||
* Function pointer in enqueued item.
|
||||
*
|
||||
* @field group
|
||||
* Group containing enqueued item (may be NULL).
|
||||
*
|
||||
* @field waiter
|
||||
* Thread waiting for completion of enqueued item (NULL if sync == 0).
|
||||
*
|
||||
* @field barrier
|
||||
* Item is a barrier on the queue (all items on serial queues are barriers).
|
||||
*
|
||||
* @field sync
|
||||
* Item was enqueued by a dispatch_sync_f/dispatch_barrier_sync_f.
|
||||
*
|
||||
* @field apply
|
||||
* Item is part of a dispatch_apply_f.
|
||||
*/
|
||||
typedef struct dispatch_introspection_queue_function_s {
|
||||
dispatch_continuation_t continuation;
|
||||
dispatch_queue_t target_queue;
|
||||
void *context;
|
||||
dispatch_function_t function;
|
||||
dispatch_group_t group;
|
||||
pthread_t waiter;
|
||||
unsigned long barrier:1,
|
||||
sync:1,
|
||||
apply:1;
|
||||
} dispatch_introspection_queue_function_s;
|
||||
typedef dispatch_introspection_queue_function_s
|
||||
*dispatch_introspection_queue_function_t;
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_introspection_object_s
|
||||
*
|
||||
* @abstract
|
||||
* A structure of introspection information for a generic dispatch object.
|
||||
*
|
||||
* @field object
|
||||
* Pointer to object.
|
||||
*
|
||||
* @field target_queue
|
||||
* Target queue of object (may be different to the queue the object is
|
||||
* currently enqueued on).
|
||||
*
|
||||
* @field type
|
||||
* Object class pointer.
|
||||
*
|
||||
* @field kind
|
||||
* String describing the object type.
|
||||
*/
|
||||
typedef struct dispatch_introspection_object_s {
|
||||
dispatch_continuation_t object;
|
||||
dispatch_queue_t target_queue;
|
||||
void *type;
|
||||
const char *kind;
|
||||
} dispatch_introspection_object_s;
|
||||
typedef dispatch_introspection_object_s *dispatch_introspection_object_t;
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_introspection_queue_s
|
||||
*
|
||||
* @abstract
|
||||
* A structure of introspection information for a dispatch queue.
|
||||
*
|
||||
* @field queue
|
||||
* Pointer to queue object.
|
||||
*
|
||||
* @field target_queue
|
||||
* Target queue of queue (may be different to the queue the queue is currently
|
||||
* enqueued on). NULL indicates queue is a root queue.
|
||||
*
|
||||
* @field label
|
||||
* Pointer to queue label.
|
||||
*
|
||||
* @field serialnum
|
||||
* Queue serial number (unique per process).
|
||||
*
|
||||
* @field width
|
||||
* Queue width (1: serial queue, UINT_MAX: concurrent queue).
|
||||
*
|
||||
* @field suspend_count
|
||||
* Number of times the queue has been suspended.
|
||||
*
|
||||
* @field enqueued
|
||||
* Queue is enqueued on another queue.
|
||||
*
|
||||
* @field barrier
|
||||
* Queue is executing a barrier item.
|
||||
*
|
||||
* @field draining
|
||||
* Queue is being drained (cannot get queue items).
|
||||
*
|
||||
* @field global
|
||||
* Queue is a global queue.
|
||||
*
|
||||
* @field main
|
||||
* Queue is the main queue.
|
||||
*/
|
||||
typedef struct dispatch_introspection_queue_s {
|
||||
dispatch_queue_t queue;
|
||||
dispatch_queue_t target_queue;
|
||||
const char *label;
|
||||
unsigned long serialnum;
|
||||
unsigned int width;
|
||||
unsigned int suspend_count;
|
||||
unsigned long enqueued:1,
|
||||
barrier:1,
|
||||
draining:1,
|
||||
global:1,
|
||||
main:1;
|
||||
} dispatch_introspection_queue_s;
|
||||
typedef dispatch_introspection_queue_s *dispatch_introspection_queue_t;
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_introspection_source_s
|
||||
*
|
||||
* @abstract
|
||||
* A structure of introspection information for a dispatch source.
|
||||
*
|
||||
* @field source
|
||||
* Pointer to source object.
|
||||
*
|
||||
* @field target_queue
|
||||
* Target queue of source (may be different to the queue the source is currently
|
||||
* enqueued on).
|
||||
*
|
||||
* @field type
|
||||
* Source type (kevent filter)
|
||||
*
|
||||
* @field handle
|
||||
* Source handle (monitored entity).
|
||||
*
|
||||
* @field context
|
||||
* Context pointer passed to source handler. Pointer to handler block if
|
||||
* handler_is_block == 1.
|
||||
*
|
||||
* @field handler
|
||||
* Source handler function. Function pointer of handler block if
|
||||
* handler_is_block == 1.
|
||||
*
|
||||
* @field suspend_count
|
||||
* Number of times the source has been suspended.
|
||||
*
|
||||
* @field enqueued
|
||||
* Source is enqueued on a queue.
|
||||
*
|
||||
* @field handler_is_block
|
||||
* Source handler is a block.
|
||||
*
|
||||
* @field timer
|
||||
* Source is a timer.
|
||||
*
|
||||
* @field after
|
||||
* Source is a dispatch_after timer.
|
||||
*/
|
||||
typedef struct dispatch_introspection_source_s {
|
||||
dispatch_source_t source;
|
||||
dispatch_queue_t target_queue;
|
||||
unsigned long type;
|
||||
unsigned long handle;
|
||||
void *context;
|
||||
dispatch_function_t handler;
|
||||
unsigned int suspend_count;
|
||||
unsigned long enqueued:1,
|
||||
handler_is_block:1,
|
||||
timer:1,
|
||||
after:1,
|
||||
is_xpc:1;
|
||||
} dispatch_introspection_source_s;
|
||||
typedef dispatch_introspection_source_s *dispatch_introspection_source_t;
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_introspection_queue_thread_s
|
||||
*
|
||||
* @abstract
|
||||
* A structure of introspection information about a thread executing items for
|
||||
* a dispatch queue.
|
||||
*
|
||||
* @field object
|
||||
* Pointer to thread object.
|
||||
*
|
||||
* @field thread
|
||||
* Thread executing items for a queue.
|
||||
*
|
||||
* @field queue
|
||||
* Queue introspection information. The queue.queue field is NULL if this thread
|
||||
* is not currently executing items for a queue.
|
||||
*/
|
||||
typedef struct dispatch_introspection_queue_thread_s {
|
||||
dispatch_continuation_t object;
|
||||
pthread_t thread;
|
||||
dispatch_introspection_queue_s queue;
|
||||
} dispatch_introspection_queue_thread_s;
|
||||
typedef dispatch_introspection_queue_thread_s
|
||||
*dispatch_introspection_queue_thread_t;
|
||||
|
||||
/*!
|
||||
* @enum dispatch_introspection_queue_item_type
|
||||
*
|
||||
* @abstract
|
||||
* Types of items enqueued on a dispatch queue.
|
||||
*/
|
||||
enum dispatch_introspection_queue_item_type {
|
||||
dispatch_introspection_queue_item_type_none = 0x0,
|
||||
dispatch_introspection_queue_item_type_block = 0x11,
|
||||
dispatch_introspection_queue_item_type_function = 0x12,
|
||||
dispatch_introspection_queue_item_type_object = 0x100,
|
||||
dispatch_introspection_queue_item_type_queue = 0x101,
|
||||
dispatch_introspection_queue_item_type_source = 0x42,
|
||||
};
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_introspection_queue_item_s
|
||||
*
|
||||
* @abstract
|
||||
* A structure of introspection information about an item enqueued on a
|
||||
* dispatch queue.
|
||||
*
|
||||
* @field type
|
||||
* Indicates which of the union members applies to this item.
|
||||
*/
|
||||
typedef struct dispatch_introspection_queue_item_s {
|
||||
unsigned long type; // dispatch_introspection_queue_item_type
|
||||
union {
|
||||
dispatch_introspection_queue_block_s block;
|
||||
dispatch_introspection_queue_function_s function;
|
||||
dispatch_introspection_object_s object;
|
||||
dispatch_introspection_queue_s queue;
|
||||
dispatch_introspection_source_s source;
|
||||
};
|
||||
} dispatch_introspection_queue_item_s;
|
||||
typedef dispatch_introspection_queue_item_s
|
||||
*dispatch_introspection_queue_item_t;
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_introspection_hook_queue_create_t
|
||||
*
|
||||
* @abstract
|
||||
* A function pointer called when a dispatch queue is created.
|
||||
*
|
||||
* @param queue_info
|
||||
* Pointer to queue introspection structure.
|
||||
*/
|
||||
typedef void (*dispatch_introspection_hook_queue_create_t)(
|
||||
dispatch_introspection_queue_t queue_info);
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_introspection_hook_queue_dispose_t
|
||||
*
|
||||
* @abstract
|
||||
* A function pointer called when a dispatch queue is destroyed.
|
||||
*
|
||||
* @param queue_info
|
||||
* Pointer to queue introspection structure.
|
||||
*/
|
||||
typedef void (*dispatch_introspection_hook_queue_dispose_t)(
|
||||
dispatch_introspection_queue_t queue_info);
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_introspection_hook_queue_item_enqueue_t
|
||||
*
|
||||
* @abstract
|
||||
* A function pointer called when an item is enqueued onto a dispatch queue.
|
||||
*
|
||||
* @param queue
|
||||
* Pointer to queue.
|
||||
*
|
||||
* @param item
|
||||
* Pointer to item introspection structure.
|
||||
*/
|
||||
typedef void (*dispatch_introspection_hook_queue_item_enqueue_t)(
|
||||
dispatch_queue_t queue, dispatch_introspection_queue_item_t item);
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_introspection_hook_queue_item_dequeue_t
|
||||
*
|
||||
* @abstract
|
||||
* A function pointer called when an item is dequeued from a dispatch queue.
|
||||
*
|
||||
* @param queue
|
||||
* Pointer to queue.
|
||||
*
|
||||
* @param item
|
||||
* Pointer to item introspection structure.
|
||||
*/
|
||||
typedef void (*dispatch_introspection_hook_queue_item_dequeue_t)(
|
||||
dispatch_queue_t queue, dispatch_introspection_queue_item_t item);
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_introspection_hook_queue_item_complete_t
|
||||
*
|
||||
* @abstract
|
||||
* A function pointer called when an item previously dequeued from a dispatch
|
||||
* queue has completed processing.
|
||||
*
|
||||
* @discussion
|
||||
* The object pointer value passed to this function pointer must be treated as a
|
||||
* value only. It is intended solely for matching up with an earlier call to a
|
||||
* dequeue hook function pointer by comparing to the first member of the
|
||||
* dispatch_introspection_queue_item_t structure. It must NOT be dereferenced
|
||||
* or e.g. passed to dispatch_introspection_queue_item_get_info(), the memory
|
||||
* that was backing it may have been reused at the time this hook is called.
|
||||
*
|
||||
* @param object
|
||||
* Opaque dentifier for completed item. Must NOT be dereferenced.
|
||||
*/
|
||||
typedef void (*dispatch_introspection_hook_queue_item_complete_t)(
|
||||
dispatch_continuation_t object);
|
||||
|
||||
/*!
|
||||
* @enum dispatch_introspection_runtime_event
|
||||
*
|
||||
* @abstract
|
||||
* Types for major events the dispatch runtime goes through as sent by
|
||||
* the runtime_event hook.
|
||||
*
|
||||
* @const dispatch_introspection_runtime_event_worker_event_delivery
|
||||
* A worker thread was unparked to deliver some kernel events.
|
||||
* There may be an unpark event if the thread will pick up a queue to drain.
|
||||
* There always is a worker_park event when the thread is returned to the pool.
|
||||
* `ptr` is the queue for which events are being delivered, or NULL (for generic
|
||||
* events).
|
||||
* `value` is the number of events delivered.
|
||||
*
|
||||
* @const dispatch_introspection_runtime_event_worker_unpark
|
||||
* A worker thread junst unparked (sent from the context of the thread).
|
||||
* `ptr` is the queue for which the thread unparked.
|
||||
* `value` is 0.
|
||||
*
|
||||
* @const dispatch_introspection_runtime_event_worker_request
|
||||
* `ptr` is set to the queue on behalf of which the thread request is made.
|
||||
* `value` is the number of threads requested.
|
||||
*
|
||||
* @const dispatch_introspection_runtime_event_worker_park
|
||||
* A worker thread is about to park (sent from the context of the thread).
|
||||
* `ptr` and `value` are 0.
|
||||
*
|
||||
* @const dispatch_introspection_runtime_event_sync_wait
|
||||
* A caller of dispatch_sync or dispatch_async_and_wait hit contention.
|
||||
* `ptr` is the queue that caused the initial contention.
|
||||
* `value` is 0.
|
||||
*
|
||||
* @const dispatch_introspection_runtime_event_async_sync_handoff
|
||||
* @const dispatch_introspection_runtime_event_sync_sync_handoff
|
||||
* @const dispatch_introspection_runtime_event_sync_async_handoff
|
||||
*
|
||||
* A queue is being handed off from a thread to another due to respectively:
|
||||
* - async/sync contention
|
||||
* - sync/sync contention
|
||||
* - sync/async contention
|
||||
*
|
||||
* `ptr` is set to dispatch_queue_t which is handed off to the next thread.
|
||||
* `value` is 0.
|
||||
*/
|
||||
#ifndef __DISPATCH_BUILDING_DISPATCH__
|
||||
enum dispatch_introspection_runtime_event {
|
||||
dispatch_introspection_runtime_event_worker_event_delivery = 1,
|
||||
dispatch_introspection_runtime_event_worker_unpark = 2,
|
||||
dispatch_introspection_runtime_event_worker_request = 3,
|
||||
dispatch_introspection_runtime_event_worker_park = 4,
|
||||
|
||||
dispatch_introspection_runtime_event_sync_wait = 10,
|
||||
dispatch_introspection_runtime_event_async_sync_handoff = 11,
|
||||
dispatch_introspection_runtime_event_sync_sync_handoff = 12,
|
||||
dispatch_introspection_runtime_event_sync_async_handoff = 13,
|
||||
};
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_introspection_hook_runtime_event_t
|
||||
*
|
||||
* @abstract
|
||||
* A function pointer called for various runtime events.
|
||||
*
|
||||
* @discussion
|
||||
* The actual payloads are discussed in the documentation of the
|
||||
* dispatch_introspection_runtime_event enum.
|
||||
*/
|
||||
typedef void (*dispatch_introspection_hook_runtime_event_t)(
|
||||
enum dispatch_introspection_runtime_event event,
|
||||
void *ptr, unsigned long long value);
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_introspection_hooks_s
|
||||
*
|
||||
* @abstract
|
||||
* A structure of function pointer hooks into libdispatch.
|
||||
*/
|
||||
typedef struct dispatch_introspection_hooks_s {
|
||||
dispatch_introspection_hook_queue_create_t queue_create;
|
||||
dispatch_introspection_hook_queue_dispose_t queue_dispose;
|
||||
dispatch_introspection_hook_queue_item_enqueue_t queue_item_enqueue;
|
||||
dispatch_introspection_hook_queue_item_dequeue_t queue_item_dequeue;
|
||||
dispatch_introspection_hook_queue_item_complete_t queue_item_complete;
|
||||
dispatch_introspection_hook_runtime_event_t runtime_event;
|
||||
void *_reserved[4];
|
||||
} dispatch_introspection_hooks_s;
|
||||
typedef dispatch_introspection_hooks_s *dispatch_introspection_hooks_t;
|
||||
|
||||
/*!
|
||||
* @function dispatch_introspection_get_queues
|
||||
*
|
||||
* @abstract
|
||||
* Retrieve introspection information about all dispatch queues in the process,
|
||||
* in batches of specified size.
|
||||
*
|
||||
* @discussion
|
||||
* Retrieving queue information and iterating through the list of all queues
|
||||
* must take place from a debugger context (while the rest of the process is
|
||||
* suspended).
|
||||
*
|
||||
* @param start
|
||||
* Starting point for this batch of queue information, as returned by a previous
|
||||
* call to _dispatch_introspection_get_queues().
|
||||
* Pass NULL to retrieve the initial batch.
|
||||
*
|
||||
* @param count
|
||||
* Number of queues to introspect.
|
||||
*
|
||||
* @param queues
|
||||
* Array to fill with queue information. If less than 'count' queues are left
|
||||
* in this batch, the end of valid entries in the array will be indicated
|
||||
* by an entry with NULL queue member.
|
||||
*
|
||||
* @result
|
||||
* Queue to pass to another call to _dispatch_introspection_get_queues() to
|
||||
* retrieve information about the next batch of queues. May be NULL if there
|
||||
* are no more queues to iterate over.
|
||||
*/
|
||||
extern dispatch_queue_t
|
||||
dispatch_introspection_get_queues(dispatch_queue_t start, size_t count,
|
||||
dispatch_introspection_queue_t queues);
|
||||
|
||||
/*!
|
||||
* @function dispatch_introspection_get_queue_threads
|
||||
*
|
||||
* @abstract
|
||||
* Retrieve introspection information about all threads in the process executing
|
||||
* items for dispatch queues, in batches of specified size.
|
||||
*
|
||||
* @discussion
|
||||
* Retrieving thread information and iterating through the list of all queue
|
||||
* threads must take place from a debugger context (while the rest of the
|
||||
* process is suspended).
|
||||
*
|
||||
* @param start
|
||||
* Starting point for this batch of thread information, as returned by a
|
||||
* previous call to _dispatch_introspection_get_queue_threads().
|
||||
* Pass NULL to retrieve the initial batch.
|
||||
*
|
||||
* @param count
|
||||
* Number of queue threads to introspect.
|
||||
*
|
||||
* @param threads
|
||||
* Array to fill with queue thread information. If less than 'count' threads are
|
||||
* left in this batch, the end of valid entries in the array will be indicated
|
||||
* by an entry with NULL object member.
|
||||
*
|
||||
* @result
|
||||
* Object to pass to another call to _dispatch_introspection_get_queues() to
|
||||
* retrieve information about the next batch of queues. May be NULL if there
|
||||
* are no more queues to iterate over.
|
||||
*/
|
||||
extern dispatch_continuation_t
|
||||
dispatch_introspection_get_queue_threads(dispatch_continuation_t start,
|
||||
size_t count, dispatch_introspection_queue_thread_t threads);
|
||||
|
||||
/*!
|
||||
* @function dispatch_introspection_queue_get_items
|
||||
*
|
||||
* @abstract
|
||||
* Retrieve introspection information about all items enqueued on a queue, in
|
||||
* batches of specified size.
|
||||
*
|
||||
* @discussion
|
||||
* Retrieving queue item information and iterating through a queue must take
|
||||
* place from a debugger context (while the rest of the process is suspended).
|
||||
*
|
||||
* @param queue
|
||||
* Queue to introspect.
|
||||
*
|
||||
* @param start
|
||||
* Starting point for this batch of queue item information, as returned by a
|
||||
* previous call to _dispatch_introspection_queue_get_items().
|
||||
* Pass NULL to retrieve the initial batch.
|
||||
*
|
||||
* @param count
|
||||
* Number of items to introspect.
|
||||
*
|
||||
* @param items
|
||||
* Array to fill with queue item information. If less than 'count' queues are
|
||||
* left in this batch, the end of valid entries in the array will be indicated
|
||||
* by an entry with type dispatch_introspection_queue_item_type_none.
|
||||
*
|
||||
* @result
|
||||
* Item to pass to another call to _dispatch_introspection_queue_get_items() to
|
||||
* retrieve information about the next batch of queue items. May be NULL if
|
||||
* there are no more items to iterate over.
|
||||
*/
|
||||
extern dispatch_continuation_t
|
||||
dispatch_introspection_queue_get_items(dispatch_queue_t queue,
|
||||
dispatch_continuation_t start, size_t count,
|
||||
dispatch_introspection_queue_item_t items);
|
||||
|
||||
/*!
|
||||
* @function dispatch_introspection_queue_get_info
|
||||
*
|
||||
* @abstract
|
||||
* Retrieve introspection information about a specified dispatch queue.
|
||||
*
|
||||
* @discussion
|
||||
* Retrieving queue information must take place from a debugger context (while
|
||||
* the rest of the process is suspended).
|
||||
*
|
||||
* @param queue
|
||||
* Queue to introspect.
|
||||
*
|
||||
* @result
|
||||
* Queue information struct.
|
||||
*/
|
||||
extern dispatch_introspection_queue_s
|
||||
dispatch_introspection_queue_get_info(dispatch_queue_t queue);
|
||||
|
||||
/*!
|
||||
* @function dispatch_introspection_queue_item_get_info
|
||||
*
|
||||
* @abstract
|
||||
* Retrieve introspection information about a specified dispatch queue item.
|
||||
*
|
||||
* @discussion
|
||||
* Retrieving queue item information must take place from a debugger context
|
||||
* (while the rest of the process is suspended).
|
||||
*
|
||||
* @param queue
|
||||
* Queue to introspect.
|
||||
*
|
||||
* @param item
|
||||
* Item to introspect.
|
||||
*
|
||||
* @result
|
||||
* Queue item information struct.
|
||||
*/
|
||||
extern dispatch_introspection_queue_item_s
|
||||
dispatch_introspection_queue_item_get_info(dispatch_queue_t queue,
|
||||
dispatch_continuation_t item);
|
||||
|
||||
/*!
|
||||
* @function dispatch_introspection_hooks_install
|
||||
*
|
||||
* @abstract
|
||||
* Install hook functions into libdispatch.
|
||||
*
|
||||
* @discussion
|
||||
* Installing hook functions must take place from a debugger context (while the
|
||||
* rest of the process is suspended) or early enough in the process lifecycle
|
||||
* that the process is still single-threaded.
|
||||
*
|
||||
* The caller is responsible for implementing chaining to the hooks that were
|
||||
* previously installed (if any).
|
||||
*
|
||||
* @param hooks
|
||||
* Pointer to structure of hook function pointers. Any of the structure members
|
||||
* may be NULL to indicate that the hook in question should not be installed.
|
||||
* The structure is copied on input and filled with the previously installed
|
||||
* hooks on output.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.9), ios(7.0))
|
||||
DISPATCH_EXPORT void
|
||||
dispatch_introspection_hooks_install(dispatch_introspection_hooks_t hooks);
|
||||
|
||||
/*!
|
||||
* @function dispatch_introspection_hook_callouts_enable
|
||||
*
|
||||
* @abstract
|
||||
* Enable hook callout functions in libdispatch that a debugger can break on
|
||||
* and get introspection arguments even if there are no hook functions
|
||||
* installed via dispatch_introspection_hooks_install().
|
||||
*
|
||||
* @discussion
|
||||
* Enabling hook callout functions must take place from a debugger context
|
||||
* (while the rest of the process is suspended).
|
||||
*
|
||||
* @param enable
|
||||
* Pointer to dispatch_introspection_hooks_s structure. For every structure
|
||||
* member with (any) non-NULL value, the corresponding hook callout will be
|
||||
* enabled; for every NULL member the hook callout will be disabled (if there
|
||||
* is no hook function installed).
|
||||
* As a convenience, the 'enable' pointer may itself be NULL to indicate that
|
||||
* all hook callouts should be enabled.
|
||||
*/
|
||||
extern void
|
||||
dispatch_introspection_hook_callouts_enable(
|
||||
dispatch_introspection_hooks_t enable);
|
||||
|
||||
/*!
|
||||
* @function dispatch_introspection_hook_callout_queue_create
|
||||
*
|
||||
* @abstract
|
||||
* Callout to queue creation hook that a debugger can break on.
|
||||
*/
|
||||
extern void
|
||||
dispatch_introspection_hook_callout_queue_create(
|
||||
dispatch_introspection_queue_t queue_info);
|
||||
|
||||
/*!
|
||||
* @function dispatch_introspection_hook_callout_queue_dispose
|
||||
*
|
||||
* @abstract
|
||||
* Callout to queue destruction hook that a debugger can break on.
|
||||
*/
|
||||
extern void
|
||||
dispatch_introspection_hook_callout_queue_dispose(
|
||||
dispatch_introspection_queue_t queue_info);
|
||||
|
||||
/*!
|
||||
* @function dispatch_introspection_hook_callout_queue_item_enqueue
|
||||
*
|
||||
* @abstract
|
||||
* Callout to queue enqueue hook that a debugger can break on.
|
||||
*/
|
||||
extern void
|
||||
dispatch_introspection_hook_callout_queue_item_enqueue(
|
||||
dispatch_queue_t queue, dispatch_introspection_queue_item_t item);
|
||||
|
||||
/*!
|
||||
* @function dispatch_introspection_hook_callout_queue_item_dequeue
|
||||
*
|
||||
* @abstract
|
||||
* Callout to queue dequeue hook that a debugger can break on.
|
||||
*/
|
||||
extern void
|
||||
dispatch_introspection_hook_callout_queue_item_dequeue(
|
||||
dispatch_queue_t queue, dispatch_introspection_queue_item_t item);
|
||||
|
||||
/*!
|
||||
* @function dispatch_introspection_hook_callout_queue_item_complete
|
||||
*
|
||||
* @abstract
|
||||
* Callout to queue item complete hook that a debugger can break on.
|
||||
*/
|
||||
extern void
|
||||
dispatch_introspection_hook_callout_queue_item_complete(
|
||||
dispatch_continuation_t object);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif
|
||||
416
Telegram/ThirdParty/dispatch/private/io_private.h
vendored
Normal file
416
Telegram/ThirdParty/dispatch/private/io_private.h
vendored
Normal file
@@ -0,0 +1,416 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2013 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/*
|
||||
* IMPORTANT: This header file describes INTERNAL interfaces to libdispatch
|
||||
* which are subject to change in future releases of Mac OS X. Any applications
|
||||
* relying on these interfaces WILL break.
|
||||
*/
|
||||
|
||||
#ifndef __DISPATCH_IO_PRIVATE__
|
||||
#define __DISPATCH_IO_PRIVATE__
|
||||
|
||||
#ifndef __DISPATCH_INDIRECT__
|
||||
#error "Please #include <dispatch/dispatch.h> instead of this file directly."
|
||||
#include <dispatch/base.h> // for HeaderDoc
|
||||
#endif
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_BEGIN
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/*!
|
||||
* @function dispatch_read_f
|
||||
* Schedule a read operation for asynchronous execution on the specified file
|
||||
* descriptor. The specified handler is enqueued with the data read from the
|
||||
* file descriptor when the operation has completed or an error occurs.
|
||||
*
|
||||
* The data object passed to the handler will be automatically released by the
|
||||
* system when the handler returns. It is the responsibility of the application
|
||||
* to retain, concatenate or copy the data object if it is needed after the
|
||||
* handler returns.
|
||||
*
|
||||
* The data object passed to the handler will only contain as much data as is
|
||||
* currently available from the file descriptor (up to the specified length).
|
||||
*
|
||||
* If an unrecoverable error occurs on the file descriptor, the handler will be
|
||||
* enqueued with the appropriate error code along with a data object of any data
|
||||
* that could be read successfully.
|
||||
*
|
||||
* An invocation of the handler with an error code of zero and an empty data
|
||||
* object indicates that EOF was reached.
|
||||
*
|
||||
* The system takes control of the file descriptor until the handler is
|
||||
* enqueued, and during this time file descriptor flags such as O_NONBLOCK will
|
||||
* be modified by the system on behalf of the application. It is an error for
|
||||
* the application to modify a file descriptor directly while it is under the
|
||||
* control of the system, but it may create additional dispatch I/O convenience
|
||||
* operations or dispatch I/O channels associated with that file descriptor.
|
||||
*
|
||||
* @param fd The file descriptor from which to read the data.
|
||||
* @param length The length of data to read from the file descriptor,
|
||||
* or SIZE_MAX to indicate that all of the data currently
|
||||
* available from the file descriptor should be read.
|
||||
* @param queue The dispatch queue to which the handler should be
|
||||
* submitted.
|
||||
* @param context The application-defined context parameter to pass to
|
||||
* the handler function.
|
||||
* @param handler The handler to enqueue when data is ready to be
|
||||
* delivered.
|
||||
* param context Application-defined context parameter.
|
||||
* param data The data read from the file descriptor.
|
||||
* param error An errno condition for the read operation or
|
||||
* zero if the read was successful.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.9), ios(7.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL3 DISPATCH_NONNULL5 DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_read_f(dispatch_fd_t fd,
|
||||
size_t length,
|
||||
dispatch_queue_t queue,
|
||||
void *_Nullable context,
|
||||
void (*handler)(void *_Nullable context, dispatch_data_t data, int error));
|
||||
|
||||
/*!
|
||||
* @function dispatch_write_f
|
||||
* Schedule a write operation for asynchronous execution on the specified file
|
||||
* descriptor. The specified handler is enqueued when the operation has
|
||||
* completed or an error occurs.
|
||||
*
|
||||
* If an unrecoverable error occurs on the file descriptor, the handler will be
|
||||
* enqueued with the appropriate error code along with the data that could not
|
||||
* be successfully written.
|
||||
*
|
||||
* An invocation of the handler with an error code of zero indicates that the
|
||||
* data was fully written to the channel.
|
||||
*
|
||||
* The system takes control of the file descriptor until the handler is
|
||||
* enqueued, and during this time file descriptor flags such as O_NONBLOCK will
|
||||
* be modified by the system on behalf of the application. It is an error for
|
||||
* the application to modify a file descriptor directly while it is under the
|
||||
* control of the system, but it may create additional dispatch I/O convenience
|
||||
* operations or dispatch I/O channels associated with that file descriptor.
|
||||
*
|
||||
* @param fd The file descriptor to which to write the data.
|
||||
* @param data The data object to write to the file descriptor.
|
||||
* @param queue The dispatch queue to which the handler should be
|
||||
* submitted.
|
||||
* @param context The application-defined context parameter to pass to
|
||||
* the handler function.
|
||||
* @param handler The handler to enqueue when the data has been written.
|
||||
* param context Application-defined context parameter.
|
||||
* param data The data that could not be written to the I/O
|
||||
* channel, or NULL.
|
||||
* param error An errno condition for the write operation or
|
||||
* zero if the write was successful.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.9), ios(7.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_NONNULL3 DISPATCH_NONNULL5
|
||||
DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_write_f(dispatch_fd_t fd,
|
||||
dispatch_data_t data,
|
||||
dispatch_queue_t queue,
|
||||
void *_Nullable context,
|
||||
void (*handler)(void *_Nullable context, dispatch_data_t _Nullable data,
|
||||
int error));
|
||||
|
||||
/*!
|
||||
* @function dispatch_io_create_f
|
||||
* Create a dispatch I/O channel associated with a file descriptor. The system
|
||||
* takes control of the file descriptor until the channel is closed, an error
|
||||
* occurs on the file descriptor or all references to the channel are released.
|
||||
* At that time the specified cleanup handler will be enqueued and control over
|
||||
* the file descriptor relinquished.
|
||||
*
|
||||
* While a file descriptor is under the control of a dispatch I/O channel, file
|
||||
* descriptor flags such as O_NONBLOCK will be modified by the system on behalf
|
||||
* of the application. It is an error for the application to modify a file
|
||||
* descriptor directly while it is under the control of a dispatch I/O channel,
|
||||
* but it may create additional channels associated with that file descriptor.
|
||||
*
|
||||
* @param type The desired type of I/O channel (DISPATCH_IO_STREAM
|
||||
* or DISPATCH_IO_RANDOM).
|
||||
* @param fd The file descriptor to associate with the I/O channel.
|
||||
* @param queue The dispatch queue to which the handler should be submitted.
|
||||
* @param context The application-defined context parameter to pass to
|
||||
* the cleanup handler function.
|
||||
* @param cleanup_handler The handler to enqueue when the system
|
||||
* relinquishes control over the file descriptor.
|
||||
* param context Application-defined context parameter.
|
||||
* param error An errno condition if control is relinquished
|
||||
* because channel creation failed, zero otherwise.
|
||||
* @result The newly created dispatch I/O channel or NULL if an error
|
||||
* occurred (invalid type specified).
|
||||
*/
|
||||
API_AVAILABLE(macos(10.9), ios(7.0))
|
||||
DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
|
||||
DISPATCH_NOTHROW
|
||||
dispatch_io_t
|
||||
dispatch_io_create_f(dispatch_io_type_t type,
|
||||
dispatch_fd_t fd,
|
||||
dispatch_queue_t queue,
|
||||
void *_Nullable context,
|
||||
void (*cleanup_handler)(void *_Nullable context, int error));
|
||||
|
||||
/*!
|
||||
* @function dispatch_io_create_with_path_f
|
||||
* Create a dispatch I/O channel associated with a path name. The specified
|
||||
* path, oflag and mode parameters will be passed to open(2) when the first I/O
|
||||
* operation on the channel is ready to execute and the resulting file
|
||||
* descriptor will remain open and under the control of the system until the
|
||||
* channel is closed, an error occurs on the file descriptor or all references
|
||||
* to the channel are released. At that time the file descriptor will be closed
|
||||
* and the specified cleanup handler will be enqueued.
|
||||
*
|
||||
* @param type The desired type of I/O channel (DISPATCH_IO_STREAM
|
||||
* or DISPATCH_IO_RANDOM).
|
||||
* @param path The absolute path to associate with the I/O channel.
|
||||
* @param oflag The flags to pass to open(2) when opening the file at
|
||||
* path.
|
||||
* @param mode The mode to pass to open(2) when creating the file at
|
||||
* path (i.e. with flag O_CREAT), zero otherwise.
|
||||
* @param queue The dispatch queue to which the handler should be
|
||||
* submitted.
|
||||
* @param context The application-defined context parameter to pass to
|
||||
* the cleanup handler function.
|
||||
* @param cleanup_handler The handler to enqueue when the system
|
||||
* has closed the file at path.
|
||||
* param context Application-defined context parameter.
|
||||
* param error An errno condition if control is relinquished
|
||||
* because channel creation or opening of the
|
||||
* specified file failed, zero otherwise.
|
||||
* @result The newly created dispatch I/O channel or NULL if an error
|
||||
* occurred (invalid type or non-absolute path specified).
|
||||
*/
|
||||
API_AVAILABLE(macos(10.9), ios(7.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED
|
||||
DISPATCH_WARN_RESULT DISPATCH_NOTHROW
|
||||
dispatch_io_t
|
||||
dispatch_io_create_with_path_f(dispatch_io_type_t type,
|
||||
const char *path, int oflag, mode_t mode,
|
||||
dispatch_queue_t queue,
|
||||
void *_Nullable context,
|
||||
void (*cleanup_handler)(void *_Nullable context, int error));
|
||||
|
||||
/*!
|
||||
* @function dispatch_io_create_with_io_f
|
||||
* Create a new dispatch I/O channel from an existing dispatch I/O channel.
|
||||
* The new channel inherits the file descriptor or path name associated with
|
||||
* the existing channel, but not its channel type or policies.
|
||||
*
|
||||
* If the existing channel is associated with a file descriptor, control by the
|
||||
* system over that file descriptor is extended until the new channel is also
|
||||
* closed, an error occurs on the file descriptor, or all references to both
|
||||
* channels are released. At that time the specified cleanup handler will be
|
||||
* enqueued and control over the file descriptor relinquished.
|
||||
*
|
||||
* While a file descriptor is under the control of a dispatch I/O channel, file
|
||||
* descriptor flags such as O_NONBLOCK will be modified by the system on behalf
|
||||
* of the application. It is an error for the application to modify a file
|
||||
* descriptor directly while it is under the control of a dispatch I/O channel,
|
||||
* but it may create additional channels associated with that file descriptor.
|
||||
*
|
||||
* @param type The desired type of I/O channel (DISPATCH_IO_STREAM
|
||||
* or DISPATCH_IO_RANDOM).
|
||||
* @param io The existing channel to create the new I/O channel from.
|
||||
* @param queue The dispatch queue to which the handler should be submitted.
|
||||
* @param context The application-defined context parameter to pass to
|
||||
* the cleanup handler function.
|
||||
* @param cleanup_handler The handler to enqueue when the system
|
||||
* relinquishes control over the file descriptor
|
||||
* (resp. closes the file at path) associated with
|
||||
* the existing channel.
|
||||
* param context Application-defined context parameter.
|
||||
* param error An errno condition if control is relinquished
|
||||
* because channel creation failed, zero otherwise.
|
||||
* @result The newly created dispatch I/O channel or NULL if an error
|
||||
* occurred (invalid type specified).
|
||||
*/
|
||||
API_AVAILABLE(macos(10.9), ios(7.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL2 DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED
|
||||
DISPATCH_WARN_RESULT DISPATCH_NOTHROW
|
||||
dispatch_io_t
|
||||
dispatch_io_create_with_io_f(dispatch_io_type_t type,
|
||||
dispatch_io_t io,
|
||||
dispatch_queue_t queue,
|
||||
void *_Nullable context,
|
||||
void (*cleanup_handler)(void *_Nullable context, int error));
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_io_handler_function_t
|
||||
* The prototype of I/O handler functions for dispatch I/O operations.
|
||||
*
|
||||
* @param context Application-defined context parameter.
|
||||
* @param done A flag indicating whether the operation is complete.
|
||||
* @param data The data object to be handled.
|
||||
* @param error An errno condition for the operation.
|
||||
*/
|
||||
typedef void (*dispatch_io_handler_function_t)(void *_Nullable context,
|
||||
bool done, dispatch_data_t _Nullable data, int error);
|
||||
|
||||
/*!
|
||||
* @function dispatch_io_read_f
|
||||
* Schedule a read operation for asynchronous execution on the specified I/O
|
||||
* channel. The I/O handler is enqueued one or more times depending on the
|
||||
* general load of the system and the policy specified on the I/O channel.
|
||||
*
|
||||
* Any data read from the channel is described by the dispatch data object
|
||||
* passed to the I/O handler. This object will be automatically released by the
|
||||
* system when the I/O handler returns. It is the responsibility of the
|
||||
* application to retain, concatenate or copy the data object if it is needed
|
||||
* after the I/O handler returns.
|
||||
*
|
||||
* Dispatch I/O handlers are not reentrant. The system will ensure that no new
|
||||
* I/O handler instance is invoked until the previously enqueued handler
|
||||
* function has returned.
|
||||
*
|
||||
* An invocation of the I/O handler with the done flag set indicates that the
|
||||
* read operation is complete and that the handler will not be enqueued again.
|
||||
*
|
||||
* If an unrecoverable error occurs on the I/O channel's underlying file
|
||||
* descriptor, the I/O handler will be enqueued with the done flag set, the
|
||||
* appropriate error code and a NULL data object.
|
||||
*
|
||||
* An invocation of the I/O handler with the done flag set, an error code of
|
||||
* zero and an empty data object indicates that EOF was reached.
|
||||
*
|
||||
* @param channel The dispatch I/O channel from which to read the data.
|
||||
* @param offset The offset relative to the channel position from which
|
||||
* to start reading (only for DISPATCH_IO_RANDOM).
|
||||
* @param length The length of data to read from the I/O channel, or
|
||||
* SIZE_MAX to indicate that data should be read until EOF
|
||||
* is reached.
|
||||
* @param queue The dispatch queue to which the I/O handler should be
|
||||
* submitted.
|
||||
* @param context The application-defined context parameter to pass to
|
||||
* the handler function.
|
||||
* @param io_handler The I/O handler to enqueue when data is ready to be
|
||||
* delivered.
|
||||
* param context Application-defined context parameter.
|
||||
* param done A flag indicating whether the operation is complete.
|
||||
* param data An object with the data most recently read from the
|
||||
* I/O channel as part of this read operation, or NULL.
|
||||
* param error An errno condition for the read operation or zero if
|
||||
* the read was successful.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.9), ios(7.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL4 DISPATCH_NONNULL6
|
||||
DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_io_read_f(dispatch_io_t channel,
|
||||
off_t offset,
|
||||
size_t length,
|
||||
dispatch_queue_t queue,
|
||||
void *_Nullable context,
|
||||
dispatch_io_handler_function_t io_handler);
|
||||
|
||||
/*!
|
||||
* @function dispatch_io_write_f
|
||||
* Schedule a write operation for asynchronous execution on the specified I/O
|
||||
* channel. The I/O handler is enqueued one or more times depending on the
|
||||
* general load of the system and the policy specified on the I/O channel.
|
||||
*
|
||||
* Any data remaining to be written to the I/O channel is described by the
|
||||
* dispatch data object passed to the I/O handler. This object will be
|
||||
* automatically released by the system when the I/O handler returns. It is the
|
||||
* responsibility of the application to retain, concatenate or copy the data
|
||||
* object if it is needed after the I/O handler returns.
|
||||
*
|
||||
* Dispatch I/O handlers are not reentrant. The system will ensure that no new
|
||||
* I/O handler instance is invoked until the previously enqueued handler
|
||||
* function has returned.
|
||||
*
|
||||
* An invocation of the I/O handler with the done flag set indicates that the
|
||||
* write operation is complete and that the handler will not be enqueued again.
|
||||
*
|
||||
* If an unrecoverable error occurs on the I/O channel's underlying file
|
||||
* descriptor, the I/O handler will be enqueued with the done flag set, the
|
||||
* appropriate error code and an object containing the data that could not be
|
||||
* written.
|
||||
*
|
||||
* An invocation of the I/O handler with the done flag set and an error code of
|
||||
* zero indicates that the data was fully written to the channel.
|
||||
*
|
||||
* @param channel The dispatch I/O channel on which to write the data.
|
||||
* @param offset The offset relative to the channel position from which
|
||||
* to start writing (only for DISPATCH_IO_RANDOM).
|
||||
* @param data The data to write to the I/O channel. The data object
|
||||
* will be retained by the system until the write operation
|
||||
* is complete.
|
||||
* @param queue The dispatch queue to which the I/O handler should be
|
||||
* submitted.
|
||||
* @param context The application-defined context parameter to pass to
|
||||
* the handler function.
|
||||
* @param io_handler The I/O handler to enqueue when data has been delivered.
|
||||
* param context Application-defined context parameter.
|
||||
* param done A flag indicating whether the operation is complete.
|
||||
* param data An object of the data remaining to be
|
||||
* written to the I/O channel as part of this write
|
||||
* operation, or NULL.
|
||||
* param error An errno condition for the write operation or zero
|
||||
* if the write was successful.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.9), ios(7.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NONNULL4
|
||||
DISPATCH_NONNULL6 DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_io_write_f(dispatch_io_t channel,
|
||||
off_t offset,
|
||||
dispatch_data_t data,
|
||||
dispatch_queue_t queue,
|
||||
void *_Nullable context,
|
||||
dispatch_io_handler_function_t io_handler);
|
||||
|
||||
/*!
|
||||
* @function dispatch_io_barrier_f
|
||||
* Schedule a barrier operation on the specified I/O channel; all previously
|
||||
* scheduled operations on the channel will complete before the provided
|
||||
* barrier function is enqueued onto the global queue determined by the
|
||||
* channel's target queue, and no subsequently scheduled operations will start
|
||||
* until the barrier function has returned.
|
||||
*
|
||||
* If multiple channels are associated with the same file descriptor, a barrier
|
||||
* operation scheduled on any of these channels will act as a barrier across all
|
||||
* channels in question, i.e. all previously scheduled operations on any of the
|
||||
* channels will complete before the barrier function is enqueued, and no
|
||||
* operations subsequently scheduled on any of the channels will start until the
|
||||
* barrier function has returned.
|
||||
*
|
||||
* While the barrier function is running, it may safely operate on the channel's
|
||||
* underlying file descriptor with fsync(2), lseek(2) etc. (but not close(2)).
|
||||
*
|
||||
* @param channel The dispatch I/O channel to schedule the barrier on.
|
||||
* @param context The application-defined context parameter to pass to
|
||||
* the barrier function.
|
||||
* @param barrier The barrier function.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.9), ios(7.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_io_barrier_f(dispatch_io_t channel,
|
||||
void *_Nullable context,
|
||||
dispatch_function_t barrier);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_END
|
||||
|
||||
#endif /* __DISPATCH_IO_PRIVATE__ */
|
||||
101
Telegram/ThirdParty/dispatch/private/layout_private.h
vendored
Normal file
101
Telegram/ThirdParty/dispatch/private/layout_private.h
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2014 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#ifndef __DISPATCH_LAYOUT_PRIVATE__
|
||||
#define __DISPATCH_LAYOUT_PRIVATE__
|
||||
|
||||
#ifndef __DISPATCH_INDIRECT__
|
||||
#error "Please #include <dispatch/private.h> instead of this file directly."
|
||||
#include <dispatch/base.h> // for HeaderDoc
|
||||
#endif
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT const struct dispatch_queue_offsets_s {
|
||||
// always add new fields at the end
|
||||
const uint16_t dqo_version;
|
||||
const uint16_t dqo_label;
|
||||
const uint16_t dqo_label_size;
|
||||
const uint16_t dqo_flags;
|
||||
const uint16_t dqo_flags_size;
|
||||
const uint16_t dqo_serialnum;
|
||||
const uint16_t dqo_serialnum_size;
|
||||
const uint16_t dqo_width;
|
||||
const uint16_t dqo_width_size;
|
||||
const uint16_t dqo_running;
|
||||
const uint16_t dqo_running_size;
|
||||
// fields added in dqo_version 5:
|
||||
const uint16_t dqo_suspend_cnt;
|
||||
const uint16_t dqo_suspend_cnt_size;
|
||||
const uint16_t dqo_target_queue;
|
||||
const uint16_t dqo_target_queue_size;
|
||||
const uint16_t dqo_priority;
|
||||
const uint16_t dqo_priority_size;
|
||||
} dispatch_queue_offsets;
|
||||
|
||||
#if DISPATCH_LAYOUT_SPI
|
||||
/*!
|
||||
* @group Data Structure Layout SPI
|
||||
* SPI intended for CoreSymbolication only
|
||||
*/
|
||||
|
||||
API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
DISPATCH_EXPORT const struct dispatch_tsd_indexes_s {
|
||||
// always add new fields at the end
|
||||
const uint16_t dti_version;
|
||||
const uint16_t dti_queue_index;
|
||||
const uint16_t dti_voucher_index;
|
||||
const uint16_t dti_qos_class_index;
|
||||
/* version 3 */
|
||||
const uint16_t dti_continuation_cache_index;
|
||||
} dispatch_tsd_indexes;
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
|
||||
#include <malloc/malloc.h>
|
||||
|
||||
API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
|
||||
DISPATCH_EXPORT const struct dispatch_allocator_layout_s {
|
||||
const uint16_t dal_version;
|
||||
/* version 1 */
|
||||
/* Pointer to the allocator metadata address, points to NULL if unused */
|
||||
void **const dal_allocator_zone;
|
||||
/* Magical "isa" for allocations that are on freelists */
|
||||
void *const *const dal_deferred_free_isa;
|
||||
/* Size of allocations made in the magazine */
|
||||
const uint16_t dal_allocation_size;
|
||||
/* fields used by the enumerator */
|
||||
const uint16_t dal_magazine_size;
|
||||
const uint16_t dal_first_allocation_offset;
|
||||
const uint16_t dal_allocation_isa_offset;
|
||||
/* Enumerates allocated continuations */
|
||||
kern_return_t (*dal_enumerator)(task_t remote_task,
|
||||
const struct dispatch_allocator_layout_s *remote_allocator_layout,
|
||||
vm_address_t zone_address, memory_reader_t reader,
|
||||
void (^recorder)(vm_address_t dc_address, void *dc_mem,
|
||||
size_t size, bool *stop));
|
||||
} dispatch_allocator_layout;
|
||||
#endif // TARGET_OS_MAC
|
||||
#endif // DISPATCH_LAYOUT_SPI
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif // __DISPATCH_LAYOUT_PRIVATE__
|
||||
1155
Telegram/ThirdParty/dispatch/private/mach_private.h
vendored
Normal file
1155
Telegram/ThirdParty/dispatch/private/mach_private.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
269
Telegram/ThirdParty/dispatch/private/private.h
vendored
Normal file
269
Telegram/ThirdParty/dispatch/private/private.h
vendored
Normal file
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2013 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/*
|
||||
* IMPORTANT: This header file describes INTERNAL interfaces to libdispatch
|
||||
* which are subject to change in future releases of Mac OS X. Any applications
|
||||
* relying on these interfaces WILL break.
|
||||
*/
|
||||
|
||||
#ifndef __DISPATCH_PRIVATE__
|
||||
#define __DISPATCH_PRIVATE__
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <Availability.h>
|
||||
#include <os/availability.h>
|
||||
#include <TargetConditionals.h>
|
||||
#include <os/base.h>
|
||||
#elif defined(_WIN32)
|
||||
#include <os/generic_win_base.h>
|
||||
#elif defined(__unix__)
|
||||
#include <os/generic_unix_base.h>
|
||||
#endif
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
#include <mach/boolean.h>
|
||||
#include <mach/mach.h>
|
||||
#include <mach/message.h>
|
||||
#endif
|
||||
#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#if !defined(_WIN32)
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
#if TARGET_OS_MAC
|
||||
#include <pthread/qos.h>
|
||||
#endif
|
||||
|
||||
#ifndef __DISPATCH_BUILDING_DISPATCH__
|
||||
#include <dispatch/dispatch.h>
|
||||
|
||||
#ifndef __DISPATCH_INDIRECT__
|
||||
#define __DISPATCH_INDIRECT__
|
||||
#endif
|
||||
|
||||
#include <dispatch/benchmark.h>
|
||||
#include <dispatch/queue_private.h>
|
||||
#include <dispatch/workloop_private.h>
|
||||
#include <dispatch/source_private.h>
|
||||
#if DISPATCH_MACH_SPI
|
||||
#include <dispatch/mach_private.h>
|
||||
#endif // DISPATCH_MACH_SPI
|
||||
#include <dispatch/data_private.h>
|
||||
#include <dispatch/io_private.h>
|
||||
#include <dispatch/layout_private.h>
|
||||
#include <dispatch/time_private.h>
|
||||
|
||||
#undef __DISPATCH_INDIRECT__
|
||||
#endif /* !__DISPATCH_BUILDING_DISPATCH__ */
|
||||
|
||||
// <rdar://problem/9627726> Check that public and private dispatch headers match
|
||||
#if DISPATCH_API_VERSION != 20180109 // Keep in sync with <dispatch/dispatch.h>
|
||||
#error "Dispatch header mismatch between /usr/include and /usr/local/include"
|
||||
#endif
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_BEGIN
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/*!
|
||||
* @function _dispatch_is_multithreaded
|
||||
*
|
||||
* @abstract
|
||||
* Returns true if the current process has become multithreaded by the use
|
||||
* of libdispatch functionality.
|
||||
*
|
||||
* @discussion
|
||||
* This SPI is intended for use by low-level system components that need to
|
||||
* ensure that they do not make a single-threaded process multithreaded, to
|
||||
* avoid negatively affecting child processes of a fork (without exec).
|
||||
*
|
||||
* Such components must not use any libdispatch functionality if this function
|
||||
* returns false.
|
||||
*
|
||||
* @result
|
||||
* Boolean indicating whether the process has used libdispatch and become
|
||||
* multithreaded.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.8), ios(6.0))
|
||||
DISPATCH_EXPORT DISPATCH_NOTHROW
|
||||
bool _dispatch_is_multithreaded(void);
|
||||
|
||||
/*!
|
||||
* @function _dispatch_is_fork_of_multithreaded_parent
|
||||
*
|
||||
* @abstract
|
||||
* Returns true if the current process is a child of a parent process that had
|
||||
* become multithreaded by the use of libdispatch functionality at the time of
|
||||
* fork (without exec).
|
||||
*
|
||||
* @discussion
|
||||
* This SPI is intended for use by (rare) low-level system components that need
|
||||
* to continue working on the child side of a fork (without exec) of a
|
||||
* multithreaded process.
|
||||
*
|
||||
* Such components must not use any libdispatch functionality if this function
|
||||
* returns true.
|
||||
*
|
||||
* @result
|
||||
* Boolean indicating whether the parent process had used libdispatch and
|
||||
* become multithreaded at the time of fork.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.9), ios(7.0))
|
||||
DISPATCH_EXPORT DISPATCH_NOTHROW
|
||||
bool _dispatch_is_fork_of_multithreaded_parent(void);
|
||||
|
||||
/*!
|
||||
* @function _dispatch_prohibit_transition_to_multithreaded
|
||||
*
|
||||
* @abstract
|
||||
* Sets a mode that aborts if a program tries to use dispatch.
|
||||
*
|
||||
* @discussion
|
||||
* This SPI is intended for use by programs that know they will use fork() and
|
||||
* want their children to be able to use dispatch before exec(). Such programs
|
||||
* should call _dispatch_prohibit_transition_to_multithreaded(true) as early as
|
||||
* possible, which will cause any use of dispatch API that would make the
|
||||
* process multithreaded to abort immediately.
|
||||
*
|
||||
* Once the program no longer intends to call fork() it can call
|
||||
* _dispatch_prohibit_transition_to_multithreaded(false).
|
||||
*
|
||||
* This status is not inherited by the child process, so if the behavior
|
||||
* is required after fork, _dispatch_prohibit_transition_to_multithreaded(true)
|
||||
* should be called manually in the child after fork.
|
||||
*
|
||||
* If the program already used dispatch before the guard is enabled, then
|
||||
* this function will abort immediately.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
|
||||
DISPATCH_EXPORT DISPATCH_NOTHROW
|
||||
void _dispatch_prohibit_transition_to_multithreaded(bool prohibit);
|
||||
|
||||
/*
|
||||
* dispatch_time convenience macros
|
||||
*/
|
||||
|
||||
#define _dispatch_time_after_nsec(t) \
|
||||
dispatch_time(DISPATCH_TIME_NOW, (t))
|
||||
#define _dispatch_time_after_usec(t) \
|
||||
dispatch_time(DISPATCH_TIME_NOW, (t) * NSEC_PER_USEC)
|
||||
#define _dispatch_time_after_msec(t) \
|
||||
dispatch_time(DISPATCH_TIME_NOW, (t) * NSEC_PER_MSEC)
|
||||
#define _dispatch_time_after_sec(t) \
|
||||
dispatch_time(DISPATCH_TIME_NOW, (t) * NSEC_PER_SEC)
|
||||
|
||||
/*
|
||||
* SPI for CoreFoundation/Foundation ONLY
|
||||
*/
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
#define DISPATCH_COCOA_COMPAT 1
|
||||
#elif defined(__linux__) || defined(__FreeBSD__) || defined(_WIN32)
|
||||
#define DISPATCH_COCOA_COMPAT 1
|
||||
#else
|
||||
#define DISPATCH_COCOA_COMPAT 0
|
||||
#endif
|
||||
|
||||
#if DISPATCH_COCOA_COMPAT
|
||||
|
||||
#define DISPATCH_CF_SPI_VERSION 20160712
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
typedef mach_port_t dispatch_runloop_handle_t;
|
||||
#elif defined(__linux__) || defined(__FreeBSD__)
|
||||
typedef int dispatch_runloop_handle_t;
|
||||
#elif defined(_WIN32)
|
||||
typedef void *dispatch_runloop_handle_t;
|
||||
#else
|
||||
#error "runloop support not implemented on this platform"
|
||||
#endif
|
||||
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_CONST DISPATCH_WARN_RESULT DISPATCH_NOTHROW
|
||||
dispatch_runloop_handle_t
|
||||
_dispatch_get_main_queue_port_4CF(void);
|
||||
|
||||
API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
|
||||
DISPATCH_EXPORT DISPATCH_NOTHROW
|
||||
dispatch_runloop_handle_t
|
||||
_dispatch_get_main_queue_handle_4CF(void);
|
||||
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NOTHROW
|
||||
void
|
||||
_dispatch_main_queue_callback_4CF(void *_Null_unspecified msg);
|
||||
|
||||
API_AVAILABLE(macos(10.9), ios(7.0))
|
||||
DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
|
||||
DISPATCH_NOTHROW
|
||||
dispatch_queue_serial_t
|
||||
_dispatch_runloop_root_queue_create_4CF(const char *_Nullable label,
|
||||
unsigned long flags);
|
||||
|
||||
API_AVAILABLE(macos(10.9), ios(7.0))
|
||||
DISPATCH_EXPORT DISPATCH_WARN_RESULT DISPATCH_NOTHROW
|
||||
dispatch_runloop_handle_t
|
||||
_dispatch_runloop_root_queue_get_port_4CF(dispatch_queue_t queue);
|
||||
|
||||
#if TARGET_OS_MAC
|
||||
API_AVAILABLE(macos(10.13.2), ios(11.2), tvos(11.2), watchos(4.2))
|
||||
DISPATCH_EXPORT DISPATCH_WARN_RESULT DISPATCH_NOTHROW
|
||||
bool
|
||||
_dispatch_source_will_reenable_kevent_4NW(dispatch_source_t source);
|
||||
#endif
|
||||
|
||||
API_AVAILABLE(macos(10.9), ios(7.0))
|
||||
DISPATCH_EXPORT DISPATCH_NOTHROW
|
||||
void
|
||||
_dispatch_runloop_root_queue_wakeup_4CF(dispatch_queue_t queue);
|
||||
|
||||
API_AVAILABLE(macos(10.9), ios(7.0))
|
||||
DISPATCH_EXPORT DISPATCH_WARN_RESULT DISPATCH_NOTHROW
|
||||
bool
|
||||
_dispatch_runloop_root_queue_perform_4CF(dispatch_queue_t queue);
|
||||
|
||||
API_AVAILABLE(macos(10.9), ios(7.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
void
|
||||
_dispatch_source_set_runloop_timer_4CF(dispatch_source_t source,
|
||||
dispatch_time_t start, uint64_t interval, uint64_t leeway);
|
||||
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT
|
||||
void *_Nonnull (*_Nullable _dispatch_begin_NSAutoReleasePool)(void);
|
||||
|
||||
API_AVAILABLE(macos(10.6), ios(4.0))
|
||||
DISPATCH_EXPORT
|
||||
void (*_Nullable _dispatch_end_NSAutoReleasePool)(void *);
|
||||
|
||||
#endif /* DISPATCH_COCOA_COMPAT */
|
||||
|
||||
API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NOTHROW
|
||||
void
|
||||
_dispatch_poll_for_events_4launchd(void);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_END
|
||||
|
||||
#endif // __DISPATCH_PRIVATE__
|
||||
503
Telegram/ThirdParty/dispatch/private/queue_private.h
vendored
Normal file
503
Telegram/ThirdParty/dispatch/private/queue_private.h
vendored
Normal file
@@ -0,0 +1,503 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2013 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/*
|
||||
* IMPORTANT: This header file describes INTERNAL interfaces to libdispatch
|
||||
* which are subject to change in future releases of Mac OS X. Any applications
|
||||
* relying on these interfaces WILL break.
|
||||
*/
|
||||
|
||||
#ifndef __DISPATCH_QUEUE_PRIVATE__
|
||||
#define __DISPATCH_QUEUE_PRIVATE__
|
||||
|
||||
#ifndef __DISPATCH_INDIRECT__
|
||||
#error "Please #include <dispatch/private.h> instead of this file directly."
|
||||
#include <dispatch/base.h> // for HeaderDoc
|
||||
#endif
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_BEGIN
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/*!
|
||||
* @enum dispatch_queue_flags_t
|
||||
*
|
||||
* @constant DISPATCH_QUEUE_OVERCOMMIT
|
||||
* The queue will create a new thread for invoking blocks, regardless of how
|
||||
* busy the computer is.
|
||||
*/
|
||||
enum {
|
||||
DISPATCH_QUEUE_OVERCOMMIT = 0x2ull,
|
||||
};
|
||||
|
||||
|
||||
/*!
|
||||
* @function dispatch_set_qos_class
|
||||
*
|
||||
* @abstract
|
||||
* Sets the QOS class on a dispatch queue, source or mach channel.
|
||||
*
|
||||
* @discussion
|
||||
* This is equivalent to using dispatch_queue_make_attr_with_qos_class()
|
||||
* when creating a dispatch queue, but is availabile on additional dispatch
|
||||
* object types.
|
||||
*
|
||||
* When configured in this manner, the specified QOS class will be used over
|
||||
* the assigned QOS of workitems submitted asynchronously to this object,
|
||||
* unless the workitem has been created with ENFORCE semantics
|
||||
* (see DISPATCH_BLOCK_ENFORCE_QOS_CLASS).
|
||||
*
|
||||
* Calling this function will supersede any prior calls to
|
||||
* dispatch_set_qos_class() or dispatch_set_qos_class_floor().
|
||||
*
|
||||
* @param object
|
||||
* A dispatch queue, source or mach channel to configure.
|
||||
* The object must be inactive, and can't be a workloop.
|
||||
*
|
||||
* Passing another object type or an object that has been activated is undefined
|
||||
* and will cause the process to be terminated.
|
||||
*
|
||||
* @param qos_class
|
||||
* A QOS class value:
|
||||
* - QOS_CLASS_USER_INTERACTIVE
|
||||
* - QOS_CLASS_USER_INITIATED
|
||||
* - QOS_CLASS_DEFAULT
|
||||
* - QOS_CLASS_UTILITY
|
||||
* - QOS_CLASS_BACKGROUND
|
||||
* Passing any other value is undefined.
|
||||
*
|
||||
* @param relative_priority
|
||||
* A relative priority within the QOS class. This value is a negative
|
||||
* offset from the maximum supported scheduler priority for the given class.
|
||||
* Passing a value greater than zero or less than QOS_MIN_RELATIVE_PRIORITY
|
||||
* is undefined.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_set_qos_class(dispatch_object_t object,
|
||||
dispatch_qos_class_t qos_class, int relative_priority);
|
||||
|
||||
/*!
|
||||
* @function dispatch_set_qos_class_floor
|
||||
*
|
||||
* @abstract
|
||||
* Sets the QOS class floor on a dispatch queue, source, workloop or mach
|
||||
* channel.
|
||||
*
|
||||
* @discussion
|
||||
* The QOS class of workitems submitted to this object asynchronously will be
|
||||
* elevated to at least the specified QOS class floor.
|
||||
* Unlike dispatch_set_qos_class(), the QOS of the workitem will be used if
|
||||
* higher than the floor even when the workitem has been created without
|
||||
* "ENFORCE" semantics.
|
||||
*
|
||||
* Setting the QOS class floor is equivalent to the QOS effects of configuring
|
||||
* a target queue whose QOS class has been set with dispatch_set_qos_class().
|
||||
*
|
||||
* Calling this function will supersede any prior calls to
|
||||
* dispatch_set_qos_class() or dispatch_set_qos_class_floor().
|
||||
*
|
||||
* @param object
|
||||
* A dispatch queue, workloop, source or mach channel to configure.
|
||||
* The object must be inactive.
|
||||
*
|
||||
* Passing another object type or an object that has been activated is undefined
|
||||
* and will cause the process to be terminated.
|
||||
*
|
||||
* @param qos_class
|
||||
* A QOS class value:
|
||||
* - QOS_CLASS_USER_INTERACTIVE
|
||||
* - QOS_CLASS_USER_INITIATED
|
||||
* - QOS_CLASS_DEFAULT
|
||||
* - QOS_CLASS_UTILITY
|
||||
* - QOS_CLASS_BACKGROUND
|
||||
* Passing any other value is undefined.
|
||||
*
|
||||
* @param relative_priority
|
||||
* A relative priority within the QOS class. This value is a negative
|
||||
* offset from the maximum supported scheduler priority for the given class.
|
||||
* Passing a value greater than zero or less than QOS_MIN_RELATIVE_PRIORITY
|
||||
* is undefined.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_set_qos_class_floor(dispatch_object_t object,
|
||||
dispatch_qos_class_t qos_class, int relative_priority);
|
||||
|
||||
/*!
|
||||
* @function dispatch_set_qos_class_fallback
|
||||
*
|
||||
* @abstract
|
||||
* Sets the fallback QOS class on a dispatch queue, source, workloop or mach
|
||||
* channel.
|
||||
*
|
||||
* @discussion
|
||||
* Workitems submitted asynchronously to this object that don't have an assigned
|
||||
* QOS class will use the specified QOS class as a fallback. This interface
|
||||
* doesn't support relative priority.
|
||||
*
|
||||
* Workitems without an assigned QOS are:
|
||||
* - workitems submitted from the context of a thread opted-out of QOS,
|
||||
* - workitems created with the DISPATCH_BLOCK_DETACHED or
|
||||
* DISPATCH_BLOCK_NO_QOS_CLASS flags,
|
||||
* - XPC messages sent with xpc_connection_send_notification(),
|
||||
* - XPC connection and dispatch source handlers.
|
||||
*
|
||||
* Calling both dispatch_set_qos_class_fallback() and dispatch_set_qos_class()
|
||||
* on an object will only apply the effect of dispatch_set_qos_class().
|
||||
*
|
||||
* A QOS class fallback must always be at least as high as the current QOS
|
||||
* floor for the dispatch queue hierarchy, else it is ignored.
|
||||
*
|
||||
* When no QOS fallback has been explicitly specified:
|
||||
* - queues on hierarchies without a QOS class or QOS class floor have
|
||||
* a fallback of QOS_CLASS_DEFAULT,
|
||||
* - queues on hierarchies with a QOS class or QOS class floor configured will
|
||||
* also use that QOS class as a fallback.
|
||||
*
|
||||
* @param object
|
||||
* A dispatch queue, workloop, source or mach channel to configure.
|
||||
* The object must be inactive.
|
||||
*
|
||||
* Passing another object type or an object that has been activated is undefined
|
||||
* and will cause the process to be terminated.
|
||||
*
|
||||
* @param qos_class
|
||||
* A QOS class value:
|
||||
* - QOS_CLASS_USER_INTERACTIVE
|
||||
* - QOS_CLASS_USER_INITIATED
|
||||
* - QOS_CLASS_DEFAULT
|
||||
* - QOS_CLASS_UTILITY
|
||||
* - QOS_CLASS_BACKGROUND
|
||||
* Passing any other value is undefined.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_set_qos_class_fallback(dispatch_object_t object,
|
||||
dispatch_qos_class_t qos_class);
|
||||
|
||||
#define DISPATCH_QUEUE_FLAGS_MASK (DISPATCH_QUEUE_OVERCOMMIT)
|
||||
|
||||
// On FreeBSD pthread_attr_t is a typedef to a pointer type
|
||||
#if defined(__FreeBSD__)
|
||||
# define DISPATCH_QUEUE_NULLABLE_PTHREAD_ATTR_PTR _Nullable
|
||||
#else
|
||||
# define DISPATCH_QUEUE_NULLABLE_PTHREAD_ATTR_PTR
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @function dispatch_queue_attr_make_with_overcommit
|
||||
*
|
||||
* @discussion
|
||||
* Returns a dispatch queue attribute value with the overcommit flag set to the
|
||||
* specified value.
|
||||
*
|
||||
* This attribute only makes sense when the specified queue is targeted at
|
||||
* a root queue. Passing this attribute to dispatch_queue_create_with_target()
|
||||
* with a target queue that is not a root queue will result in an assertion and
|
||||
* the process being terminated.
|
||||
*
|
||||
* It is recommended to not specify a target queue at all when using this
|
||||
* attribute and to use dispatch_queue_attr_make_with_qos_class() to select the
|
||||
* appropriate QOS class instead.
|
||||
*
|
||||
* Queues created with this attribute cannot change target after having been
|
||||
* activated. See dispatch_set_target_queue() and dispatch_activate().
|
||||
*
|
||||
* @param attr
|
||||
* A queue attribute value to be combined with the overcommit flag, or NULL.
|
||||
*
|
||||
* @param overcommit
|
||||
* Boolean overcommit flag.
|
||||
*
|
||||
* @return
|
||||
* Returns an attribute value which may be provided to dispatch_queue_create().
|
||||
* This new value combines the attributes specified by the 'attr' parameter and
|
||||
* the overcommit flag.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.10), ios(8.0))
|
||||
DISPATCH_EXPORT DISPATCH_WARN_RESULT DISPATCH_PURE DISPATCH_NOTHROW
|
||||
dispatch_queue_attr_t
|
||||
dispatch_queue_attr_make_with_overcommit(dispatch_queue_attr_t _Nullable attr,
|
||||
bool overcommit);
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_queue_priority_t
|
||||
*
|
||||
* @constant DISPATCH_QUEUE_PRIORITY_NON_INTERACTIVE
|
||||
* Items dispatched to the queue will run at non-interactive priority.
|
||||
* This priority level is intended for user-initiated application activity that
|
||||
* is long-running and CPU or IO intensive and that the user is actively waiting
|
||||
* on, but that should not interfere with interactive use of the application.
|
||||
*
|
||||
* This global queue priority level is mapped to QOS_CLASS_UTILITY.
|
||||
*/
|
||||
#define DISPATCH_QUEUE_PRIORITY_NON_INTERACTIVE INT8_MIN
|
||||
|
||||
/*!
|
||||
* @function dispatch_queue_set_label_nocopy
|
||||
*
|
||||
* @abstract
|
||||
* Set the label for a given queue, without copying the input string.
|
||||
*
|
||||
* @discussion
|
||||
* The queue must have been initially created with a NULL label, else using
|
||||
* this function to set the queue label is undefined.
|
||||
*
|
||||
* The caller of this function must make sure the label pointer remains valid
|
||||
* while it is used as the queue label and while any callers to
|
||||
* dispatch_queue_get_label() may have obtained it. Since the queue lifetime
|
||||
* may extend past the last release, it is advised to call this function with
|
||||
* a constant string or NULL before the queue is released, or to destroy the
|
||||
* label from a finalizer for that queue.
|
||||
*
|
||||
* This function should be called before any work item could call
|
||||
* dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL) or from the context of
|
||||
* the queue itself.
|
||||
*
|
||||
* @param queue
|
||||
* The queue to adjust. Attempts to set the label of the main queue or a global
|
||||
* concurrent queue will be ignored.
|
||||
*
|
||||
* @param label
|
||||
* The new label for the queue.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_queue_set_label_nocopy(dispatch_queue_t queue,
|
||||
const char * _Nullable label);
|
||||
|
||||
/*!
|
||||
* @function dispatch_queue_set_width
|
||||
*
|
||||
* @abstract
|
||||
* Set the width of concurrency for a given queue. The width of a serial queue
|
||||
* is one.
|
||||
*
|
||||
* @discussion
|
||||
* This SPI is DEPRECATED and will be removed in a future release.
|
||||
* Uses of this SPI to make a queue concurrent by setting its width to LONG_MAX
|
||||
* should be replaced by passing DISPATCH_QUEUE_CONCURRENT to
|
||||
* dispatch_queue_create().
|
||||
* Uses of this SPI to limit queue concurrency are not recommended and should
|
||||
* be replaced by alternative mechanisms such as a dispatch semaphore created
|
||||
* with the desired concurrency width.
|
||||
*
|
||||
* @param queue
|
||||
* The queue to adjust. Attempts to set the width of the main queue or a global
|
||||
* concurrent queue will be ignored.
|
||||
*
|
||||
* @param width
|
||||
* The new maximum width of concurrency depending on available resources.
|
||||
* If zero is passed, then the value is promoted to one.
|
||||
* Negative values are magic values that map to automatic width values.
|
||||
* Unknown negative values default to DISPATCH_QUEUE_WIDTH_MAX_LOGICAL_CPUS.
|
||||
*/
|
||||
#define DISPATCH_QUEUE_WIDTH_ACTIVE_CPUS -1
|
||||
#define DISPATCH_QUEUE_WIDTH_MAX_PHYSICAL_CPUS -2
|
||||
#define DISPATCH_QUEUE_WIDTH_MAX_LOGICAL_CPUS -3
|
||||
|
||||
API_DEPRECATED("Use dispatch_queue_create(name, DISPATCH_QUEUE_CONCURRENT)",
|
||||
macos(10.6,10.10), ios(4.0,8.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_queue_set_width(dispatch_queue_t dq, long width);
|
||||
|
||||
#if defined(__BLOCKS__) && defined(__APPLE__)
|
||||
/*!
|
||||
* @function dispatch_pthread_root_queue_create
|
||||
*
|
||||
* @abstract
|
||||
* Creates a new concurrent dispatch root queue with a pthread-based pool of
|
||||
* worker threads owned by the application.
|
||||
*
|
||||
* @discussion
|
||||
* Dispatch pthread root queues are similar to the global concurrent dispatch
|
||||
* queues in that they invoke blocks concurrently, however the blocks are not
|
||||
* executed on ordinary worker threads but use a dedicated pool of pthreads not
|
||||
* shared with the global queues or any other pthread root queues.
|
||||
*
|
||||
* NOTE: this is a special-purpose facility that should only be used in very
|
||||
* limited circumstances, in almost all cases the global concurrent queues
|
||||
* should be preferred. While this facility allows for more flexibility in
|
||||
* configuring worker threads for special needs it comes at the cost of
|
||||
* increased overall memory usage due to reduced thread sharing and higher
|
||||
* latency in worker thread bringup.
|
||||
*
|
||||
* Dispatch pthread root queues do not support suspension, application context
|
||||
* and change of width or of target queue. They can however be used as the
|
||||
* target queue for serial or concurrent queues obtained via
|
||||
* dispatch_queue_create() or dispatch_queue_create_with_target(), which
|
||||
* enables the blocks submitted to those queues to be processed on the root
|
||||
* queue's pthread pool.
|
||||
*
|
||||
* When a dispatch pthread root queue is no longer needed, it should be
|
||||
* released with dispatch_release(). Existing worker pthreads and pending blocks
|
||||
* submitted to the root queue will hold a reference to the queue so it will not
|
||||
* be deallocated until all blocks have finished and worker threads exited.
|
||||
*
|
||||
* @param label
|
||||
* A string label to attach to the queue.
|
||||
* This parameter is optional and may be NULL.
|
||||
*
|
||||
* @param flags
|
||||
* Pass flags value returned by dispatch_pthread_root_queue_flags_pool_size()
|
||||
* or 0 if unused.
|
||||
*
|
||||
* @param attr
|
||||
* Attributes passed to pthread_create(3) when creating worker pthreads. This
|
||||
* parameter is copied and can be destroyed after this call returns.
|
||||
* This parameter is optional and may be NULL.
|
||||
*
|
||||
* @param configure
|
||||
* Configuration block called on newly created worker pthreads before any blocks
|
||||
* for the root queue are executed. The block may configure the current thread
|
||||
* as needed.
|
||||
* This parameter is optional and may be NULL.
|
||||
*
|
||||
* @result
|
||||
* The newly created dispatch pthread root queue.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.9), ios(6.0)) DISPATCH_LINUX_UNAVAILABLE()
|
||||
DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
|
||||
DISPATCH_NOTHROW
|
||||
dispatch_queue_global_t
|
||||
dispatch_pthread_root_queue_create(const char *_Nullable label,
|
||||
unsigned long flags, const pthread_attr_t DISPATCH_QUEUE_NULLABLE_PTHREAD_ATTR_PTR *_Nullable attr,
|
||||
dispatch_block_t _Nullable configure);
|
||||
|
||||
/*!
|
||||
* @function dispatch_pthread_root_queue_flags_pool_size
|
||||
*
|
||||
* @abstract
|
||||
* Returns flags argument to pass to dispatch_pthread_root_queue_create() to
|
||||
* specify the maximum size of the pthread pool to use for a pthread root queue.
|
||||
*
|
||||
* @param pool_size
|
||||
* Maximum size of the pthread pool to use for the root queue. The number of
|
||||
* pthreads created for this root queue will never exceed this number but there
|
||||
* is no guarantee that the specified number will be reached.
|
||||
* Pass 0 to specify that a default pool size determined by the system should
|
||||
* be used.
|
||||
* NOTE: passing pool_size == 1 does NOT make the pthread root queue equivalent
|
||||
* to a serial queue.
|
||||
*
|
||||
* @result
|
||||
* The flags argument to pass to dispatch_pthread_root_queue_create().
|
||||
*/
|
||||
DISPATCH_INLINE DISPATCH_ALWAYS_INLINE
|
||||
unsigned long
|
||||
dispatch_pthread_root_queue_flags_pool_size(uint8_t pool_size)
|
||||
{
|
||||
#define _DISPATCH_PTHREAD_ROOT_QUEUE_FLAG_POOL_SIZE (0x80000000ul)
|
||||
return (_DISPATCH_PTHREAD_ROOT_QUEUE_FLAG_POOL_SIZE |
|
||||
(unsigned long)pool_size);
|
||||
}
|
||||
|
||||
/*!
|
||||
* @function dispatch_pthread_root_queue_copy_current
|
||||
*
|
||||
* @abstract
|
||||
* Returns a reference to the pthread root queue object that has created the
|
||||
* currently executing thread, or NULL if the current thread is not associated
|
||||
* to a pthread root queue.
|
||||
*
|
||||
* @result
|
||||
* A new reference to a pthread root queue object or NULL.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
|
||||
DISPATCH_LINUX_UNAVAILABLE()
|
||||
DISPATCH_EXPORT DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT DISPATCH_NOTHROW
|
||||
dispatch_queue_global_t _Nullable
|
||||
dispatch_pthread_root_queue_copy_current(void);
|
||||
|
||||
/*!
|
||||
* @constant DISPATCH_APPLY_CURRENT_ROOT_QUEUE
|
||||
*
|
||||
* @discussion
|
||||
* This constant is deprecated, please use DISPATCH_APPLY_AUTO.
|
||||
*
|
||||
* DISPATCH_APPLY_AUTO also selects the current pthread root queue if
|
||||
* applicable.
|
||||
*/
|
||||
#define DISPATCH_APPLY_CURRENT_ROOT_QUEUE ((dispatch_queue_t _Nonnull)0)
|
||||
|
||||
#endif /* defined(__BLOCKS__) && defined(__APPLE__) */
|
||||
|
||||
/*!
|
||||
* @function dispatch_async_enforce_qos_class_f
|
||||
*
|
||||
* @abstract
|
||||
* Submits a function for asynchronous execution on a dispatch queue.
|
||||
*
|
||||
* @discussion
|
||||
* See dispatch_async() for details. The QOS will be enforced as if
|
||||
* this was called:
|
||||
* <code>
|
||||
* dispatch_async(queue, dispatch_block_create(DISPATCH_BLOCK_ENFORCE_QOS_CLASS, ^{
|
||||
* work(context);
|
||||
* });
|
||||
* </code>
|
||||
*
|
||||
* @param queue
|
||||
* The target dispatch queue to which the function is submitted.
|
||||
* The system will hold a reference on the target queue until the function
|
||||
* has returned.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @param context
|
||||
* The application-defined context parameter to pass to the function.
|
||||
*
|
||||
* @param work
|
||||
* The application-defined function to invoke on the target queue. The first
|
||||
* parameter passed to this function is the context provided to
|
||||
* dispatch_async_f().
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.11), ios(9.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_async_enforce_qos_class_f(dispatch_queue_t queue,
|
||||
void *_Nullable context, dispatch_function_t work);
|
||||
|
||||
#ifdef __ANDROID__
|
||||
/*!
|
||||
* @function _dispatch_install_thread_detach_callback
|
||||
*
|
||||
* @param cb
|
||||
* Function to be called before each worker thread exits to detach JVM.
|
||||
*
|
||||
* Hook to be able to detach threads from the Java JVM before they exit.
|
||||
* If JNI has been used on a thread on Android it needs to have been
|
||||
* "detached" before the thread exits or the application will crash.
|
||||
*/
|
||||
DISPATCH_EXPORT
|
||||
void _dispatch_install_thread_detach_callback(void (*cb)(void));
|
||||
#endif
|
||||
|
||||
__END_DECLS
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_END
|
||||
|
||||
#endif
|
||||
649
Telegram/ThirdParty/dispatch/private/source_private.h
vendored
Normal file
649
Telegram/ThirdParty/dispatch/private/source_private.h
vendored
Normal file
@@ -0,0 +1,649 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2013 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/*
|
||||
* IMPORTANT: This header file describes INTERNAL interfaces to libdispatch
|
||||
* which are subject to change in future releases of Mac OS X. Any applications
|
||||
* relying on these interfaces WILL break.
|
||||
*/
|
||||
|
||||
#ifndef __DISPATCH_SOURCE_PRIVATE__
|
||||
#define __DISPATCH_SOURCE_PRIVATE__
|
||||
|
||||
#ifndef __DISPATCH_INDIRECT__
|
||||
#error "Please #include <dispatch/private.h> instead of this file directly."
|
||||
#include <dispatch/base.h> // for HeaderDoc
|
||||
#endif
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_BEGIN
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/*!
|
||||
* @const DISPATCH_SOURCE_TYPE_INTERVAL
|
||||
* @discussion A dispatch source that submits the event handler block at a
|
||||
* specified time interval, phase-aligned with all other interval sources on
|
||||
* the system that have the same interval value.
|
||||
*
|
||||
* The initial submission of the event handler will occur at some point during
|
||||
* the first time interval after the source is created (assuming the source is
|
||||
* resumed at that time).
|
||||
*
|
||||
* By default, the unit for the interval value is milliseconds and the leeway
|
||||
* (maximum amount of time any individual handler submission may be deferred to
|
||||
* align with other system activity) for the source is fixed at interval/2.
|
||||
*
|
||||
* If the DISPATCH_INTERVAL_UI_ANIMATION flag is specified, the unit for the
|
||||
* interval value is animation frames (1/60th of a second) and the leeway is
|
||||
* fixed at one frame.
|
||||
*
|
||||
* The handle is the interval value in milliseconds or frames.
|
||||
* The mask specifies which flags from dispatch_source_timer_flags_t to apply.
|
||||
*
|
||||
* Starting with macOS 10.14, iOS 12, dispatch_source_set_timer()
|
||||
* can be used on such sources, and its arguments are used as follow:
|
||||
* - start:
|
||||
* must be DISPATCH_TIME_NOW or DISPATCH_TIME_FOREVER.
|
||||
* DISPATCH_TIME_NOW will enable the timer, and align its phase, and
|
||||
* DISPATCH_TIME_FOREVER will disable the timer as usual.*
|
||||
* - interval:
|
||||
* its unit is in milliseconds by default, or frames if the source
|
||||
* was created with the DISPATCH_INTERVAL_UI_ANIMATION flag.
|
||||
* - leeway:
|
||||
* per-thousands of the interval (valid values range from 0 to 1000).
|
||||
* If ~0ull is passed, the default leeway for the interval is used instead.
|
||||
*/
|
||||
#define DISPATCH_SOURCE_TYPE_INTERVAL (&_dispatch_source_type_interval)
|
||||
API_AVAILABLE(macos(10.9), ios(7.0))
|
||||
DISPATCH_SOURCE_TYPE_DECL(interval);
|
||||
|
||||
/*!
|
||||
* @const DISPATCH_SOURCE_TYPE_VFS
|
||||
* @discussion Apple-internal dispatch source that monitors for vfs events
|
||||
* defined by dispatch_vfs_flags_t.
|
||||
* The handle is a process identifier (pid_t).
|
||||
*/
|
||||
#define DISPATCH_SOURCE_TYPE_VFS (&_dispatch_source_type_vfs)
|
||||
API_AVAILABLE(macos(10.6), ios(4.0)) DISPATCH_LINUX_UNAVAILABLE()
|
||||
DISPATCH_SOURCE_TYPE_DECL(vfs);
|
||||
|
||||
/*!
|
||||
* @const DISPATCH_SOURCE_TYPE_VM
|
||||
* @discussion A dispatch source that monitors virtual memory
|
||||
* The mask is a mask of desired events from dispatch_source_vm_flags_t.
|
||||
* This type is deprecated, use DISPATCH_SOURCE_TYPE_MEMORYPRESSURE instead.
|
||||
*/
|
||||
#define DISPATCH_SOURCE_TYPE_VM (&_dispatch_source_type_vm)
|
||||
API_DEPRECATED_WITH_REPLACEMENT("DISPATCH_SOURCE_TYPE_MEMORYPRESSURE",
|
||||
macos(10.7,10.10), ios(4.3,8.0)) DISPATCH_LINUX_UNAVAILABLE()
|
||||
DISPATCH_SOURCE_TYPE_DECL(vm);
|
||||
|
||||
/*!
|
||||
* @const DISPATCH_SOURCE_TYPE_MEMORYSTATUS
|
||||
* @discussion A dispatch source that monitors memory status
|
||||
* The mask is a mask of desired events from
|
||||
* dispatch_source_memorystatus_flags_t.
|
||||
*/
|
||||
#define DISPATCH_SOURCE_TYPE_MEMORYSTATUS (&_dispatch_source_type_memorystatus)
|
||||
API_DEPRECATED_WITH_REPLACEMENT("DISPATCH_SOURCE_TYPE_MEMORYPRESSURE",
|
||||
macos(10.9, 10.12), ios(6.0, 10.0), tvos(6.0, 10.0), watchos(1.0, 3.0))
|
||||
DISPATCH_LINUX_UNAVAILABLE()
|
||||
DISPATCH_SOURCE_TYPE_DECL(memorystatus);
|
||||
|
||||
/*!
|
||||
* @const DISPATCH_SOURCE_TYPE_SOCK
|
||||
* @discussion A dispatch source that monitors events on socket state changes.
|
||||
*/
|
||||
#define DISPATCH_SOURCE_TYPE_SOCK (&_dispatch_source_type_sock)
|
||||
API_AVAILABLE(macos(10.8), ios(6.0)) DISPATCH_LINUX_UNAVAILABLE()
|
||||
DISPATCH_SOURCE_TYPE_DECL(sock);
|
||||
|
||||
/*!
|
||||
* @const DISPATCH_SOURCE_TYPE_NW_CHANNEL
|
||||
* @discussion A dispatch source that monitors events on a network channel.
|
||||
*/
|
||||
#define DISPATCH_SOURCE_TYPE_NW_CHANNEL (&_dispatch_source_type_nw_channel)
|
||||
API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)) DISPATCH_LINUX_UNAVAILABLE()
|
||||
DISPATCH_SOURCE_TYPE_DECL(nw_channel);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
/*!
|
||||
* @enum dispatch_source_sock_flags_t
|
||||
*
|
||||
* @constant DISPATCH_SOCK_CONNRESET
|
||||
* Received RST
|
||||
*
|
||||
* @constant DISPATCH_SOCK_READCLOSED
|
||||
* Read side is shutdown
|
||||
*
|
||||
* @constant DISPATCH_SOCK_WRITECLOSED
|
||||
* Write side is shutdown
|
||||
*
|
||||
* @constant DISPATCH_SOCK_TIMEOUT
|
||||
* Timeout: rexmt, keep-alive or persist
|
||||
*
|
||||
* @constant DISPATCH_SOCK_NOSRCADDR
|
||||
* Source address not available
|
||||
*
|
||||
* @constant DISPATCH_SOCK_IFDENIED
|
||||
* Interface denied connection
|
||||
*
|
||||
* @constant DISPATCH_SOCK_SUSPEND
|
||||
* Output queue suspended
|
||||
*
|
||||
* @constant DISPATCH_SOCK_RESUME
|
||||
* Output queue resumed
|
||||
*
|
||||
* @constant DISPATCH_SOCK_KEEPALIVE
|
||||
* TCP Keepalive received
|
||||
*
|
||||
* @constant DISPATCH_SOCK_CONNECTED
|
||||
* Socket is connected
|
||||
*
|
||||
* @constant DISPATCH_SOCK_DISCONNECTED
|
||||
* Socket is disconnected
|
||||
*
|
||||
* @constant DISPATCH_SOCK_CONNINFO_UPDATED
|
||||
* Connection info was updated
|
||||
*
|
||||
* @constant DISPATCH_SOCK_NOTIFY_ACK
|
||||
* Notify acknowledgement
|
||||
*/
|
||||
enum {
|
||||
DISPATCH_SOCK_CONNRESET = 0x00000001,
|
||||
DISPATCH_SOCK_READCLOSED = 0x00000002,
|
||||
DISPATCH_SOCK_WRITECLOSED = 0x00000004,
|
||||
DISPATCH_SOCK_TIMEOUT = 0x00000008,
|
||||
DISPATCH_SOCK_NOSRCADDR = 0x00000010,
|
||||
DISPATCH_SOCK_IFDENIED = 0x00000020,
|
||||
DISPATCH_SOCK_SUSPEND = 0x00000040,
|
||||
DISPATCH_SOCK_RESUME = 0x00000080,
|
||||
DISPATCH_SOCK_KEEPALIVE = 0x00000100,
|
||||
DISPATCH_SOCK_ADAPTIVE_WTIMO = 0x00000200,
|
||||
DISPATCH_SOCK_ADAPTIVE_RTIMO = 0x00000400,
|
||||
DISPATCH_SOCK_CONNECTED = 0x00000800,
|
||||
DISPATCH_SOCK_DISCONNECTED = 0x00001000,
|
||||
DISPATCH_SOCK_CONNINFO_UPDATED = 0x00002000,
|
||||
DISPATCH_SOCK_NOTIFY_ACK = 0x00004000,
|
||||
};
|
||||
|
||||
/*!
|
||||
* @enum dispatch_source_nw_channel_flags_t
|
||||
*
|
||||
* @constant DISPATCH_NW_CHANNEL_FLOW_ADV_UPDATE
|
||||
* Received network channel flow advisory.
|
||||
*/
|
||||
enum {
|
||||
DISPATCH_NW_CHANNEL_FLOW_ADV_UPDATE = 0x00000001,
|
||||
};
|
||||
|
||||
/*!
|
||||
* @enum dispatch_source_vfs_flags_t
|
||||
*
|
||||
* @constant DISPATCH_VFS_NOTRESP
|
||||
* Server down.
|
||||
*
|
||||
* @constant DISPATCH_VFS_NEEDAUTH
|
||||
* Server bad auth.
|
||||
*
|
||||
* @constant DISPATCH_VFS_LOWDISK
|
||||
* We're low on space.
|
||||
*
|
||||
* @constant DISPATCH_VFS_MOUNT
|
||||
* New filesystem arrived.
|
||||
*
|
||||
* @constant DISPATCH_VFS_UNMOUNT
|
||||
* Filesystem has left.
|
||||
*
|
||||
* @constant DISPATCH_VFS_DEAD
|
||||
* Filesystem is dead, needs force unmount.
|
||||
*
|
||||
* @constant DISPATCH_VFS_ASSIST
|
||||
* Filesystem needs assistance from external program.
|
||||
*
|
||||
* @constant DISPATCH_VFS_NOTRESPLOCK
|
||||
* Server lockd down.
|
||||
*
|
||||
* @constant DISPATCH_VFS_UPDATE
|
||||
* Filesystem information has changed.
|
||||
*
|
||||
* @constant DISPATCH_VFS_VERYLOWDISK
|
||||
* File system has *very* little disk space left.
|
||||
*
|
||||
* @constant DISPATCH_VFS_QUOTA
|
||||
* We hit a user quota (quotactl) for this filesystem.
|
||||
*
|
||||
* @constant DISPATCH_VFS_NEARLOWDISK
|
||||
* Filesystem is nearly full (below NEARLOWDISK level).
|
||||
*
|
||||
* @constant DISPATCH_VFS_DESIREDDISK
|
||||
* Filesystem has exceeded the DESIREDDISK level
|
||||
*
|
||||
* @constant DISPATCH_VFS_FREE_SPACE_CHANGE
|
||||
* Filesystem free space changed.
|
||||
*/
|
||||
enum {
|
||||
DISPATCH_VFS_NOTRESP = 0x0001,
|
||||
DISPATCH_VFS_NEEDAUTH = 0x0002,
|
||||
DISPATCH_VFS_LOWDISK = 0x0004,
|
||||
DISPATCH_VFS_MOUNT = 0x0008,
|
||||
DISPATCH_VFS_UNMOUNT = 0x0010,
|
||||
DISPATCH_VFS_DEAD = 0x0020,
|
||||
DISPATCH_VFS_ASSIST = 0x0040,
|
||||
DISPATCH_VFS_NOTRESPLOCK = 0x0080,
|
||||
DISPATCH_VFS_UPDATE = 0x0100,
|
||||
DISPATCH_VFS_VERYLOWDISK = 0x0200,
|
||||
DISPATCH_VFS_QUOTA = 0x1000,
|
||||
DISPATCH_VFS_NEARLOWDISK = 0x2000,
|
||||
DISPATCH_VFS_DESIREDDISK = 0x4000,
|
||||
DISPATCH_VFS_FREE_SPACE_CHANGE = 0x8000,
|
||||
};
|
||||
|
||||
/*!
|
||||
* @enum dispatch_clockid_t
|
||||
*
|
||||
* @discussion
|
||||
* These values can be used with DISPATCH_SOURCE_TYPE_TIMER as a "handle"
|
||||
* to anchor the timer to a given clock which allows for various optimizations.
|
||||
*
|
||||
* Note that using an explicit clock will make the dispatch source "strict"
|
||||
* like dispatch_source_set_mandatory_cancel_handler() does.
|
||||
*
|
||||
* @constant DISPATCH_CLOCKID_UPTIME
|
||||
* A monotonic clock that doesn't tick while the machine is asleep.
|
||||
* Equivalent to the CLOCK_UPTIME clock ID on BSD systems.
|
||||
*
|
||||
* @constant DISPATCH_CLOCKID_MONOTONIC
|
||||
* A monotonic clock that ticks while the machine sleeps.
|
||||
* Equivalent to POSIX CLOCK_MONOTONIC.
|
||||
* (Note that on Linux, CLOCK_MONOTONIC isn't conformant and doesn't tick while
|
||||
* sleeping, hence on Linux this is the same clock as CLOCK_BOOTTIME).
|
||||
*
|
||||
* @constant DISPATCH_CLOCKID_WALLTIME
|
||||
* A clock equivalent to the wall clock time, as returned by gettimeofday().
|
||||
* Equivalent to POSIX CLOCK_REALTIME.
|
||||
*
|
||||
* @constant DISPATCH_CLOCKID_REALTIME
|
||||
* An alias for DISPATCH_CLOCKID_WALLTIME to match the POSIX clock of the
|
||||
* same name.
|
||||
*/
|
||||
DISPATCH_ENUM(dispatch_clockid, uintptr_t,
|
||||
DISPATCH_CLOCKID_UPTIME DISPATCH_ENUM_API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0)) = 1,
|
||||
DISPATCH_CLOCKID_MONOTONIC DISPATCH_ENUM_API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0)) = 2,
|
||||
DISPATCH_CLOCKID_WALLTIME DISPATCH_ENUM_API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0)) = 3,
|
||||
DISPATCH_CLOCKID_REALTIME DISPATCH_ENUM_API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0)) = 3,
|
||||
);
|
||||
|
||||
/*!
|
||||
* @enum dispatch_source_timer_flags_t
|
||||
*
|
||||
* @constant DISPATCH_TIMER_BACKGROUND
|
||||
* Specifies that the timer is used to trigger low priority maintenance-level
|
||||
* activity and that the system may apply larger minimum leeway values to the
|
||||
* timer in order to align it with other system activity.
|
||||
*
|
||||
* @constant DISPATCH_INTERVAL_UI_ANIMATION
|
||||
* Specifies that the interval source is used for UI animation. The unit for
|
||||
* the interval value of such sources is frames (1/60th of a second) and the
|
||||
* leeway is fixed at one frame.
|
||||
*/
|
||||
enum {
|
||||
DISPATCH_TIMER_BACKGROUND = 0x2,
|
||||
DISPATCH_INTERVAL_UI_ANIMATION = 0x20,
|
||||
};
|
||||
|
||||
/*!
|
||||
* @enum dispatch_source_mach_send_flags_t
|
||||
*
|
||||
* @constant DISPATCH_MACH_SEND_POSSIBLE
|
||||
* The mach port corresponding to the given send right has space available
|
||||
* for messages. Delivered only once a mach_msg() to that send right with
|
||||
* options MACH_SEND_MSG|MACH_SEND_TIMEOUT|MACH_SEND_NOTIFY has returned
|
||||
* MACH_SEND_TIMED_OUT (and not again until the next such mach_msg() timeout).
|
||||
* NOTE: The source must have registered the send right for monitoring with the
|
||||
* system for such a mach_msg() to arm the send-possible notifcation, so
|
||||
* the initial send attempt must occur from a source registration handler.
|
||||
*/
|
||||
enum {
|
||||
DISPATCH_MACH_SEND_POSSIBLE = 0x8,
|
||||
};
|
||||
|
||||
/*!
|
||||
* @enum dispatch_source_proc_flags_t
|
||||
*
|
||||
* @constant DISPATCH_PROC_REAP
|
||||
* The process has been reaped by the parent process via wait*().
|
||||
* This flag is deprecated and will be removed in a future release.
|
||||
*
|
||||
* @constant DISPATCH_PROC_EXIT_STATUS
|
||||
* The process has exited. Specifying this flag allows the process exit status
|
||||
* to be retrieved from the source's status value, as returned by the
|
||||
* dispatch_source_get_extended_data() function. The macros
|
||||
* DISPATCH_PROC_EXIT_STATUS_EXITED(), DISPATCH_PROC_EXIT_STATUS_CODE(),
|
||||
* DISPATCH_PROC_EXIT_STATUS_SIGNALED(), DISPATCH_PROC_EXIT_STATUS_TERMSIG() and
|
||||
* DISPATCH_PROC_EXIT_STATUS_CORE_DUMPED() can be used to examine the status
|
||||
* value.
|
||||
*/
|
||||
enum {
|
||||
DISPATCH_PROC_REAP DISPATCH_ENUM_API_DEPRECATED("unsupported flag",
|
||||
macos(10.6,10.9), ios(4.0,7.0)) = 0x10000000,
|
||||
DISPATCH_PROC_EXIT_STATUS DISPATCH_ENUM_API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(2.0)) = 0x04000000,
|
||||
};
|
||||
|
||||
/*!
|
||||
* @enum dispatch_source_vm_flags_t
|
||||
*
|
||||
* @constant DISPATCH_VM_PRESSURE
|
||||
* The VM has experienced memory pressure.
|
||||
*/
|
||||
|
||||
enum {
|
||||
DISPATCH_VM_PRESSURE DISPATCH_ENUM_API_DEPRECATED_WITH_REPLACEMENT("DISPATCH_MEMORYPRESSURE_WARN", macos(10.7, 10.10), ios(4.3, 8.0))
|
||||
= 0x80000000,
|
||||
};
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_source_memorypressure_flags_t
|
||||
* Type of dispatch_source_memorypressure flags
|
||||
*
|
||||
* @constant DISPATCH_MEMORYPRESSURE_LOW_SWAP
|
||||
* The system's memory pressure state has entered the "low swap" condition.
|
||||
* Restricted to the root user.
|
||||
*/
|
||||
enum {
|
||||
DISPATCH_MEMORYPRESSURE_LOW_SWAP DISPATCH_ENUM_API_AVAILABLE(macos(10.10), ios(8.0)) = 0x08,
|
||||
};
|
||||
|
||||
/*!
|
||||
* @enum dispatch_source_memorystatus_flags_t
|
||||
* @warning Deprecated, see DISPATCH_MEMORYPRESSURE_*
|
||||
*/
|
||||
enum {
|
||||
DISPATCH_MEMORYSTATUS_PRESSURE_NORMAL
|
||||
DISPATCH_ENUM_API_DEPRECATED_WITH_REPLACEMENT("DISPATCH_MEMORYPRESSURE_NORMAL", macos(10.9, 10.12),
|
||||
ios(6.0, 10.0), tvos(6.0, 10.0), watchos(1.0, 3.0)) = 0x01,
|
||||
DISPATCH_MEMORYSTATUS_PRESSURE_WARN
|
||||
DISPATCH_ENUM_API_DEPRECATED_WITH_REPLACEMENT("DISPATCH_MEMORYPRESSURE_WARN", macos(10.9, 10.12),
|
||||
ios(6.0, 10.0), tvos(6.0, 10.0), watchos(1.0, 3.0)) = 0x02,
|
||||
DISPATCH_MEMORYSTATUS_PRESSURE_CRITICAL
|
||||
DISPATCH_ENUM_API_DEPRECATED_WITH_REPLACEMENT("DISPATCH_MEMORYPRESSURE_CRITICAL", macos(10.9, 10.12),
|
||||
ios(6.0, 10.0), tvos(6.0, 10.0), watchos(1.0, 3.0)) = 0x04,
|
||||
DISPATCH_MEMORYSTATUS_LOW_SWAP
|
||||
DISPATCH_ENUM_API_DEPRECATED_WITH_REPLACEMENT("DISPATCH_MEMORYPRESSURE_LOW_SWAP", macos(10.9, 10.12),
|
||||
ios(6.0, 10.0), tvos(6.0, 10.0), watchos(1.0, 3.0)) = 0x08,
|
||||
};
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_source_memorypressure_flags_t
|
||||
* Type of dispatch_source_memorypressure flags
|
||||
*
|
||||
* @constant DISPATCH_MEMORYPRESSURE_PROC_LIMIT_WARN
|
||||
* The memory of the process has crossed 80% of its high watermark limit.
|
||||
*
|
||||
* @constant DISPATCH_MEMORYPRESSURE_PROC_LIMIT_CRITICAL
|
||||
* The memory of the process has reached 100% of its high watermark limit.
|
||||
*
|
||||
* @constant DISPATCH_MEMORYPRESSURE_MSL_STATUS
|
||||
* Mask for enabling/disabling malloc stack logging.
|
||||
*/
|
||||
enum {
|
||||
DISPATCH_MEMORYPRESSURE_PROC_LIMIT_WARN DISPATCH_ENUM_API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0)) = 0x10,
|
||||
|
||||
DISPATCH_MEMORYPRESSURE_PROC_LIMIT_CRITICAL DISPATCH_ENUM_API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0)) = 0x20,
|
||||
|
||||
DISPATCH_MEMORYPRESSURE_MSL_STATUS DISPATCH_ENUM_API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0)) = 0xf0000000,
|
||||
};
|
||||
|
||||
/*!
|
||||
* Macros to check the exit status obtained from the status field of the
|
||||
* structure returned by the dispatch_source_get_extended_data() function for a
|
||||
* source of type DISPATCH_SOURCE_TYPE_PROC when DISPATCH_PROC_EXIT_STATUS has
|
||||
* been requested.
|
||||
*
|
||||
* DISPATCH_PROC_EXIT_STATUS_EXITED returns whether the process exited. If this
|
||||
* is true, the exit status can be obtained from DISPATCH_PROC_EXIT_STATUS_CODE.
|
||||
*
|
||||
* DISPATCH_PROC_EXIT_STATUS_SIGNALED returns whether the process was terminated
|
||||
* by a signal.
|
||||
*
|
||||
* DISPATCH_PROC_EXIT_STATUS_TERMSIG returns the signal that caused the process
|
||||
* to terminate, or 0 if the process was not terminated by a signal.
|
||||
*
|
||||
* DISPATCH_PROC_EXIT_STATUS_CORE_DUMPED returns whether a core dump of the
|
||||
* process was created.
|
||||
*/
|
||||
#define DISPATCH_PROC_EXIT_STATUS_EXITED(status) ((bool)WIFEXITED(status))
|
||||
#define DISPATCH_PROC_EXIT_STATUS_CODE(status) ((int)WEXITSTATUS(status))
|
||||
#define DISPATCH_PROC_EXIT_STATUS_SIGNALED(status) ((bool)WIFSIGNALED(status))
|
||||
#define DISPATCH_PROC_EXIT_STATUS_TERMSIG(status) ((int)WTERMSIG(status))
|
||||
#define DISPATCH_PROC_EXIT_STATUS_CORE_DUMPED(status) ((bool)WCOREDUMP(status))
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/*!
|
||||
* @function dispatch_source_set_mandatory_cancel_handler
|
||||
*
|
||||
* @abstract
|
||||
* Sets the event handler block for the given dispatch source, and indicates
|
||||
* that calling dispatch_source_cancel() is mandatory for this source object.
|
||||
*
|
||||
* @discussion
|
||||
* The cancellation handler (if specified) will be submitted to the source's
|
||||
* target queue in response to a call to dispatch_source_cancel() once the
|
||||
* system has released all references to the source's underlying handle and
|
||||
* the source's event handler block has returned.
|
||||
*
|
||||
* When this function has been used used to set a cancellation handler, then
|
||||
* the following result in an assertion and the process being terminated:
|
||||
* - releasing the last reference on the dispatch source without having
|
||||
* cancelled it by calling dispatch_source_cancel();
|
||||
* - changing any handler after the source has been activated;
|
||||
* - changing the target queue of the source after it has been activated.
|
||||
*
|
||||
* IMPORTANT:
|
||||
* Source cancellation and a cancellation handler are required for file
|
||||
* descriptor and mach port based sources in order to safely close the
|
||||
* descriptor or destroy the port. Making the cancellation handler of such
|
||||
* sources mandatory is strongly recommended.
|
||||
* Closing the descriptor or port before the cancellation handler is invoked may
|
||||
* result in a race condition. If a new descriptor is allocated with the same
|
||||
* value as the recently closed descriptor while the source's event handler is
|
||||
* still running, the event handler may read/write data to the wrong descriptor.
|
||||
*
|
||||
* @param source
|
||||
* The dispatch source to modify.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @param handler
|
||||
* The cancellation handler block to submit to the source's target queue.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*/
|
||||
#ifdef __BLOCKS__
|
||||
API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_source_set_mandatory_cancel_handler(dispatch_source_t source,
|
||||
dispatch_block_t handler);
|
||||
#endif /* __BLOCKS__ */
|
||||
|
||||
/*!
|
||||
* @function dispatch_source_set_mandatory_cancel_handler_f
|
||||
*
|
||||
* @abstract
|
||||
* Sets the event handler function for the given dispatch source, and causes an
|
||||
* assertion if this source is released before having been explicitly canceled.
|
||||
*
|
||||
* @discussion
|
||||
* See dispatch_source_set_mandatory_cancel_handler() for more details.
|
||||
*
|
||||
* @param source
|
||||
* The dispatch source to modify.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @param handler
|
||||
* The cancellation handler function to submit to the source's target queue.
|
||||
* The context parameter passed to the event handler function is the current
|
||||
* context of the dispatch source at the time the handler call is made.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_source_set_mandatory_cancel_handler_f(dispatch_source_t source,
|
||||
dispatch_function_t handler);
|
||||
|
||||
/*!
|
||||
* @function dispatch_source_cancel_and_wait
|
||||
*
|
||||
* @abstract
|
||||
* Synchronously cancel the dispatch source, preventing any further invocation
|
||||
* of its event handler block.
|
||||
*
|
||||
* @discussion
|
||||
* Cancellation prevents any further invocation of handler blocks for the
|
||||
* specified dispatch source, but does not interrupt a handler block that is
|
||||
* already in progress.
|
||||
*
|
||||
* When this function returns, any handler block that may have been in progress
|
||||
* has returned, the specified source has been unregistered and it is safe to
|
||||
* reclaim any system resource (such as file descriptors or mach ports) that
|
||||
* the specified source was monitoring.
|
||||
*
|
||||
* If the specified dispatch source is inactive, it will be activated as a side
|
||||
* effect of calling this function.
|
||||
*
|
||||
* It is possible to call this function from several threads concurrently,
|
||||
* and it is the responsibility of the callers to synchronize reclaiming the
|
||||
* associated system resources.
|
||||
*
|
||||
* This function is not subject to priority inversion when it is waiting on
|
||||
* a handler block still in progress, unlike patterns based on waiting on
|
||||
* a dispatch semaphore or a dispatch group signaled (or left) from the source
|
||||
* cancel handler.
|
||||
*
|
||||
* This function must not be called if the specified source has a cancel
|
||||
* handler set, or from the context of its handler blocks.
|
||||
*
|
||||
* This function must not be called from the context of the target queue of
|
||||
* the specified source or from any queue that synchronizes with it. Note that
|
||||
* calling dispatch_source_cancel() from such a context already guarantees
|
||||
* that no handler is in progress, and that no new event will be delivered.
|
||||
*
|
||||
* This function must not be called on sources suspended with an explicit
|
||||
* call to dispatch_suspend(), or being concurrently activated on another
|
||||
* thread.
|
||||
*
|
||||
* @param source
|
||||
* The dispatch source to be canceled.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.12), ios(10.0), tvos(10.0), watchos(3.0))
|
||||
DISPATCH_EXPORT DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_source_cancel_and_wait(dispatch_source_t source);
|
||||
|
||||
#if __has_include(<mach/mach.h>)
|
||||
/*!
|
||||
* @typedef dispatch_mig_callback_t
|
||||
*
|
||||
* @abstract
|
||||
* The signature of a function that handles Mach message delivery and response.
|
||||
*/
|
||||
typedef boolean_t (*dispatch_mig_callback_t)(mach_msg_header_t *message,
|
||||
mach_msg_header_t *reply);
|
||||
|
||||
API_AVAILABLE(macos(10.6), ios(4.0)) DISPATCH_LINUX_UNAVAILABLE()
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
mach_msg_return_t
|
||||
dispatch_mig_server(dispatch_source_t ds, size_t maxmsgsz,
|
||||
dispatch_mig_callback_t callback);
|
||||
|
||||
/*!
|
||||
* @function dispatch_mach_msg_get_context
|
||||
*
|
||||
* @abstract
|
||||
* Extract the context pointer from a mach message trailer.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.6), ios(4.0)) DISPATCH_LINUX_UNAVAILABLE()
|
||||
DISPATCH_EXPORT DISPATCH_PURE DISPATCH_WARN_RESULT DISPATCH_NONNULL_ALL
|
||||
DISPATCH_NOTHROW
|
||||
void *_Nullable
|
||||
dispatch_mach_msg_get_context(mach_msg_header_t *msg);
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_source_extended_data_t
|
||||
*
|
||||
* @abstract
|
||||
* Type used by dispatch_source_get_extended_data() to return a consistent
|
||||
* snapshot of the data and status of a dispatch source.
|
||||
*/
|
||||
typedef struct dispatch_source_extended_data_s {
|
||||
unsigned long data;
|
||||
unsigned long status;
|
||||
} *dispatch_source_extended_data_t;
|
||||
|
||||
/*!
|
||||
* @function dispatch_source_get_extended_data
|
||||
*
|
||||
* @abstract
|
||||
* Returns the current data and status values for a dispatch source.
|
||||
*
|
||||
* @discussion
|
||||
* This function is intended to be called from within the event handler block.
|
||||
* The result of calling this function outside of the event handler callback is
|
||||
* undefined.
|
||||
*
|
||||
* @param source
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @param data
|
||||
* A pointer to a dispatch_source_extended_data_s in which the data and status
|
||||
* will be returned. The data field is populated with the value that would be
|
||||
* returned by dispatch_source_get_data(). The value of the status field should
|
||||
* be interpreted according to the type of the dispatch source:
|
||||
*
|
||||
* DISPATCH_SOURCE_TYPE_PROC: dispatch_source_proc_exit_flags_t
|
||||
*
|
||||
* If called from the event handler of a data source type not listed above, the
|
||||
* status value is undefined.
|
||||
*
|
||||
* @param size
|
||||
* The size of the specified structure. Should be set to
|
||||
* sizeof(dispatch_source_extended_data_s).
|
||||
*
|
||||
* @result
|
||||
* The size of the structure returned in *data, which will never be greater than
|
||||
* the value of the size argument. If this is less than the value of the size
|
||||
* argument, the remaining space in data will have been populated with zeroes.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.13), ios(11.0), tvos(11.0), watchos(4.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_WARN_RESULT DISPATCH_PURE
|
||||
DISPATCH_NOTHROW
|
||||
size_t
|
||||
dispatch_source_get_extended_data(dispatch_source_t source,
|
||||
dispatch_source_extended_data_t data, size_t size);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_END
|
||||
|
||||
#endif
|
||||
87
Telegram/ThirdParty/dispatch/private/time_private.h
vendored
Normal file
87
Telegram/ThirdParty/dispatch/private/time_private.h
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 20017 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/*
|
||||
* IMPORTANT: This header file describes INTERNAL interfaces to libdispatch
|
||||
* which are subject to change in future releases. Any applications relying on
|
||||
* these interfaces WILL break.
|
||||
*/
|
||||
|
||||
#ifndef __DISPATCH_TIME_PRIVATE__
|
||||
#define __DISPATCH_TIME_PRIVATE__
|
||||
|
||||
#ifndef __DISPATCH_INDIRECT__
|
||||
#error "Please #include <dispatch/private.h> instead of this file directly."
|
||||
#include <dispatch/base.h> // for HeaderDoc
|
||||
#endif
|
||||
|
||||
/*
|
||||
* @constant DISPATCH_MONOTONICTIME_NOW
|
||||
* A dispatch_time_t value that corresponds to the current value of the
|
||||
* platform's monotonic clock. On Apple platforms, this clock is based on
|
||||
* mach_continuous_time(). Use this value with the dispatch_time() function to
|
||||
* derive a time value for a timer in monotonic time (i.e. a timer that
|
||||
* continues to tick while the system is asleep). For example:
|
||||
*
|
||||
* dispatch_time_t t = dispatch_time(DISPATCH_MONOTONICTIME_NOW,5*NSEC_PER_SEC);
|
||||
* dispatch_source_t ds = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,
|
||||
* 0, 0, q);
|
||||
* dispatch_source_set_event_handler(ds, ^{ ... });
|
||||
* dispatch_source_set_timer(ds, t, 10 * NSEC_PER_SEC, 0);
|
||||
* dispatch_activate(ds);
|
||||
*/
|
||||
enum {
|
||||
DISPATCH_MONOTONICTIME_NOW DISPATCH_ENUM_API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0)) = (1ull << 63)
|
||||
};
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
// Helper macros for up time, montonic time and wall time.
|
||||
#define _dispatch_uptime_after_nsec(t) \
|
||||
dispatch_time(DISPATCH_TIME_NOW, (t))
|
||||
#define _dispatch_uptime_after_usec(t) \
|
||||
dispatch_time(DISPATCH_TIME_NOW, (t) * NSEC_PER_USEC)
|
||||
#define _dispatch_uptime_after_msec(t) \
|
||||
dispatch_time(DISPATCH_TIME_NOW, (t) * NSEC_PER_MSEC)
|
||||
#define _dispatch_uptime_after_sec(t) \
|
||||
dispatch_time(DISPATCH_TIME_NOW, (t) * NSEC_PER_SEC)
|
||||
|
||||
#define _dispatch_monotonictime_after_nsec(t) \
|
||||
dispatch_time(DISPATCH_MONOTONICTIME_NOW, (t))
|
||||
#define _dispatch_monotonictime_after_usec(t) \
|
||||
dispatch_time(DISPATCH_MONOTONICTIME_NOW, (t) * NSEC_PER_USEC)
|
||||
#define _dispatch_monotonictime_after_msec(t) \
|
||||
dispatch_time(DISPATCH_MONOTONICTIME_NOW, (t) * NSEC_PER_MSEC)
|
||||
#define _dispatch_monotonictime_after_sec(t) \
|
||||
dispatch_time(DISPATCH_MONOTONICTIME_NOW, (t) * NSEC_PER_SEC)
|
||||
|
||||
#define _dispatch_walltime_after_nsec(t) \
|
||||
dispatch_time(DISPATCH_WALLTIME_NOW, (t))
|
||||
#define _dispatch_walltime_after_usec(t) \
|
||||
dispatch_time(DISPATCH_WALLTIME_NOW, (t) * NSEC_PER_USEC)
|
||||
#define _dispatch_walltime_after_msec(t) \
|
||||
dispatch_time(DISPATCH_WALLTIME_NOW, (t) * NSEC_PER_MSEC)
|
||||
#define _dispatch_walltime_after_sec(t) \
|
||||
dispatch_time(DISPATCH_WALLTIME_NOW, (t) * NSEC_PER_SEC)
|
||||
|
||||
#endif // __APPLE__
|
||||
|
||||
#endif
|
||||
|
||||
440
Telegram/ThirdParty/dispatch/private/workloop_private.h
vendored
Normal file
440
Telegram/ThirdParty/dispatch/private/workloop_private.h
vendored
Normal file
@@ -0,0 +1,440 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2018 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/*
|
||||
* IMPORTANT: This header file describes INTERNAL interfaces to libdispatch
|
||||
* which are subject to change in future releases of Mac OS X. Any applications
|
||||
* relying on these interfaces WILL break.
|
||||
*/
|
||||
|
||||
#ifndef __DISPATCH_WORKLOOP_PRIVATE__
|
||||
#define __DISPATCH_WORKLOOP_PRIVATE__
|
||||
|
||||
#ifndef __DISPATCH_INDIRECT__
|
||||
#error "Please #include <dispatch/private.h> instead of this file directly."
|
||||
#include <dispatch/base.h> // for HeaderDoc
|
||||
#endif
|
||||
|
||||
/******************************************************************************\
|
||||
*
|
||||
* THIS FILE IS AN IN-PROGRESS INTERFACE THAT IS SUBJECT TO CHANGE
|
||||
*
|
||||
\******************************************************************************/
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_BEGIN
|
||||
|
||||
__BEGIN_DECLS
|
||||
|
||||
/*!
|
||||
* @typedef dispatch_workloop_t
|
||||
*
|
||||
* @abstract
|
||||
* Dispatch workloops invoke workitems submitted to them in priority order.
|
||||
*
|
||||
* @discussion
|
||||
* A dispatch workloop is a flavor of dispatch_queue_t that is a priority
|
||||
* ordered queue (using the QOS class of the submitted workitems as the
|
||||
* ordering).
|
||||
*
|
||||
* Between each workitem invocation, the workloop will evaluate whether higher
|
||||
* priority workitems have since been submitted and execute these first.
|
||||
*
|
||||
* Serial queues targeting a workloop maintain FIFO execution of their
|
||||
* workitems. However, the workloop may reorder workitems submitted to
|
||||
* independent serial queues targeting it with respect to each other,
|
||||
* based on their priorities.
|
||||
*
|
||||
* A dispatch workloop is a "subclass" of dispatch_queue_t which can be passed
|
||||
* to all APIs accepting a dispatch queue, except for functions from the
|
||||
* dispatch_sync() family. dispatch_async_and_wait() must be used for workloop
|
||||
* objects. Functions from the dispatch_sync() family on queues targeting
|
||||
* a workloop are still permitted but discouraged for performance reasons.
|
||||
*/
|
||||
#if defined(__DISPATCH_BUILDING_DISPATCH__) && !defined(__OBJC__)
|
||||
typedef struct dispatch_workloop_s *dispatch_workloop_t;
|
||||
#else
|
||||
DISPATCH_DECL_SUBCLASS(dispatch_workloop, dispatch_queue);
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @function dispatch_workloop_create
|
||||
*
|
||||
* @abstract
|
||||
* Creates a new dispatch workloop to which workitems may be submitted.
|
||||
*
|
||||
* @param label
|
||||
* A string label to attach to the workloop.
|
||||
*
|
||||
* @result
|
||||
* The newly created dispatch workloop.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
|
||||
DISPATCH_NOTHROW
|
||||
dispatch_workloop_t
|
||||
dispatch_workloop_create(const char *_Nullable label);
|
||||
|
||||
/*!
|
||||
* @function dispatch_workloop_create_inactive
|
||||
*
|
||||
* @abstract
|
||||
* Creates a new inactive dispatch workloop that can be setup and then
|
||||
* activated.
|
||||
*
|
||||
* @discussion
|
||||
* Creating an inactive workloop allows for it to receive further configuration
|
||||
* before it is activated, and workitems can be submitted to it.
|
||||
*
|
||||
* Submitting workitems to an inactive workloop is undefined and will cause the
|
||||
* process to be terminated.
|
||||
*
|
||||
* @param label
|
||||
* A string label to attach to the workloop.
|
||||
*
|
||||
* @result
|
||||
* The newly created dispatch workloop.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_MALLOC DISPATCH_RETURNS_RETAINED DISPATCH_WARN_RESULT
|
||||
DISPATCH_NOTHROW
|
||||
dispatch_workloop_t
|
||||
dispatch_workloop_create_inactive(const char *_Nullable label);
|
||||
|
||||
/*!
|
||||
* @function dispatch_workloop_set_autorelease_frequency
|
||||
*
|
||||
* @abstract
|
||||
* Sets the autorelease frequency of the workloop.
|
||||
*
|
||||
* @discussion
|
||||
* See dispatch_queue_attr_make_with_autorelease_frequency().
|
||||
* The default policy for a workloop is
|
||||
* DISPATCH_AUTORELEASE_FREQUENCY_WORK_ITEM.
|
||||
*
|
||||
* @param workloop
|
||||
* The dispatch workloop to modify.
|
||||
*
|
||||
* This workloop must be inactive, passing an activated object is undefined
|
||||
* and will cause the process to be terminated.
|
||||
*
|
||||
* @param frequency
|
||||
* The requested autorelease frequency.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_workloop_set_autorelease_frequency(dispatch_workloop_t workloop,
|
||||
dispatch_autorelease_frequency_t frequency);
|
||||
|
||||
DISPATCH_ENUM(dispatch_workloop_param_flags, uint64_t,
|
||||
DISPATCH_WORKLOOP_NONE DISPATCH_ENUM_API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0)) = 0x0,
|
||||
DISPATCH_WORKLOOP_FIXED_PRIORITY DISPATCH_ENUM_API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0)) = 0x1,
|
||||
);
|
||||
|
||||
/*!
|
||||
* @function dispatch_workloop_set_qos_class_floor
|
||||
*
|
||||
* @abstract
|
||||
* Sets the QOS class floor of a workloop.
|
||||
*
|
||||
* @discussion
|
||||
* See dispatch_set_qos_class_floor().
|
||||
*
|
||||
* This function is strictly equivalent to dispatch_set_qos_class_floor() but
|
||||
* allows to pass extra flags.
|
||||
*
|
||||
* Using both dispatch_workloop_set_scheduler_priority() and
|
||||
* dispatch_set_qos_class_floor() or dispatch_workloop_set_qos_class_floor()
|
||||
* is undefined and will cause the process to be terminated.
|
||||
*
|
||||
* @param workloop
|
||||
* The dispatch workloop to modify.
|
||||
*
|
||||
* This workloop must be inactive, passing an activated object is undefined
|
||||
* and will cause the process to be terminated.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_workloop_set_qos_class_floor(dispatch_workloop_t workloop,
|
||||
dispatch_qos_class_t qos, int relpri, dispatch_workloop_param_flags_t flags);
|
||||
|
||||
/*!
|
||||
* @function dispatch_workloop_set_scheduler_priority
|
||||
*
|
||||
* @abstract
|
||||
* Sets the scheduler priority for a dispatch workloop.
|
||||
*
|
||||
* @discussion
|
||||
* This sets the scheduler priority of the threads that the runtime will bring
|
||||
* up to service this workloop.
|
||||
*
|
||||
* QOS propagation still functions on these workloops, but its effect on the
|
||||
* priority of the thread brought up to service this workloop is ignored.
|
||||
*
|
||||
* Using both dispatch_workloop_set_scheduler_priority() and
|
||||
* dispatch_set_qos_class_floor() or dispatch_workloop_set_qos_class_floor()
|
||||
* is undefined and will cause the process to be terminated.
|
||||
*
|
||||
* @param workloop
|
||||
* The dispatch workloop to modify.
|
||||
*
|
||||
* This workloop must be inactive, passing an activated object is undefined
|
||||
* and will cause the process to be terminated.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_workloop_set_scheduler_priority(dispatch_workloop_t workloop,
|
||||
int priority, dispatch_workloop_param_flags_t flags);
|
||||
|
||||
/*!
|
||||
* @function dispatch_workloop_set_cpupercent
|
||||
*
|
||||
* @abstract
|
||||
* Sets the cpu percent and refill attributes for a dispatch workloop.
|
||||
*
|
||||
* @discussion
|
||||
* This should only used if the workloop was also setup with the
|
||||
* DISPATCH_WORKLOOP_FIXED_PRIORITY flag as a safe guard against
|
||||
* busy loops that could starve the rest of the system forever.
|
||||
*
|
||||
* If DISPATCH_WORKLOOP_FIXED_PRIORITY wasn't passed, using this function is
|
||||
* undefined and will cause the process to be terminated.
|
||||
*
|
||||
* @param workloop
|
||||
* The dispatch workloop to modify.
|
||||
*
|
||||
* This workloop must be inactive, passing an activated object is undefined
|
||||
* and will cause the process to be terminated.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_workloop_set_cpupercent(dispatch_workloop_t workloop, uint8_t percent,
|
||||
uint32_t refillms);
|
||||
|
||||
/*!
|
||||
* @function dispatch_workloop_is_current()
|
||||
*
|
||||
* @abstract
|
||||
* Returns whether the current thread has been made by the runtime to service
|
||||
* this workloop.
|
||||
*
|
||||
* @discussion
|
||||
* Note that when using <code>dispatch_async_and_wait(workloop, ^{ ... })</code>
|
||||
* then <code>workloop</code> will be seen as the "current" one by the submitted
|
||||
* workitem, but that is not the case when using dispatch_sync() on a queue
|
||||
* targeting the workloop.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
bool
|
||||
dispatch_workloop_is_current(dispatch_workloop_t workloop);
|
||||
|
||||
/*!
|
||||
* @function dispatch_workloop_copy_current()
|
||||
*
|
||||
* @abstract
|
||||
* Returns a copy of the workoop that is being serviced on the calling thread
|
||||
* if any.
|
||||
*
|
||||
* @discussion
|
||||
* If the thread is not a workqueue thread, or is not servicing a dispatch
|
||||
* workloop, then NULL is returned.
|
||||
*
|
||||
* This returns a retained object that must be released with dispatch_release().
|
||||
*/
|
||||
API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_RETURNS_RETAINED DISPATCH_NOTHROW
|
||||
dispatch_workloop_t _Nullable
|
||||
dispatch_workloop_copy_current(void);
|
||||
|
||||
// Equivalent to dispatch_workloop_set_qos_class_floor(workoop, qos, 0, flags)
|
||||
API_DEPRECATED_WITH_REPLACEMENT("dispatch_workloop_set_qos_class_floor",
|
||||
macos(10.14,10.14), ios(12.0,12.0), tvos(12.0,12.0), watchos(5.0,5.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_workloop_set_qos_class(dispatch_workloop_t workloop,
|
||||
dispatch_qos_class_t qos, dispatch_workloop_param_flags_t flags);
|
||||
|
||||
API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_NOTHROW
|
||||
bool
|
||||
_dispatch_workloop_should_yield_4NW(void);
|
||||
|
||||
/*!
|
||||
* @function dispatch_async_and_wait
|
||||
*
|
||||
* @abstract
|
||||
* Submits a block for synchronous execution on a dispatch queue.
|
||||
*
|
||||
* @discussion
|
||||
* Submits a workitem to a dispatch queue like dispatch_async(), however
|
||||
* dispatch_async_and_wait() will not return until the workitem has finished.
|
||||
*
|
||||
* Like functions of the dispatch_sync family, dispatch_async_and_wait() is
|
||||
* subject to dead-lock (See dispatch_sync() for details).
|
||||
*
|
||||
* However, dispatch_async_and_wait() differs from functions of the
|
||||
* dispatch_sync family in two fundamental ways: how it respects queue
|
||||
* attributes and how it chooses the execution context invoking the workitem.
|
||||
*
|
||||
* <b>Differences with dispatch_sync()</b>
|
||||
*
|
||||
* Work items submitted to a queue with dispatch_async_and_wait() observe all
|
||||
* queue attributes of that queue when invoked (inluding autorelease frequency
|
||||
* or QOS class).
|
||||
*
|
||||
* When the runtime has brought up a thread to invoke the asynchronous workitems
|
||||
* already submitted to the specified queue, that servicing thread will also be
|
||||
* used to execute synchronous work submitted to the queue with
|
||||
* dispatch_async_and_wait().
|
||||
*
|
||||
* However, if the runtime has not brought up a thread to service the specified
|
||||
* queue (because it has no workitems enqueued, or only synchronous workitems),
|
||||
* then dispatch_async_and_wait() will invoke the workitem on the calling thread,
|
||||
* similar to the behaviour of functions in the dispatch_sync family.
|
||||
*
|
||||
* As an exception, if the queue the work is submitted to doesn't target
|
||||
* a global concurrent queue (for example because it targets the main queue),
|
||||
* then the workitem will never be invoked by the thread calling
|
||||
* dispatch_async_and_wait().
|
||||
*
|
||||
* In other words, dispatch_async_and_wait() is similar to submitting
|
||||
* a dispatch_block_create()d workitem to a queue and then waiting on it, as
|
||||
* shown in the code example below. However, dispatch_async_and_wait() is
|
||||
* significantly more efficient when a new thread is not required to execute
|
||||
* the workitem (as it will use the stack of the submitting thread instead of
|
||||
* requiring heap allocations).
|
||||
*
|
||||
* <code>
|
||||
* dispatch_block_t b = dispatch_block_create(0, block);
|
||||
* dispatch_async(queue, b);
|
||||
* dispatch_block_wait(b, DISPATCH_TIME_FOREVER);
|
||||
* Block_release(b);
|
||||
* </code>
|
||||
*
|
||||
* @param queue
|
||||
* The target dispatch queue to which the block is submitted.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @param block
|
||||
* The block to be invoked on the target dispatch queue.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*/
|
||||
#ifdef __BLOCKS__
|
||||
API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_async_and_wait(dispatch_queue_t queue,
|
||||
DISPATCH_NOESCAPE dispatch_block_t block);
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @function dispatch_async_and_wait_f
|
||||
*
|
||||
* @abstract
|
||||
* Submits a function for synchronous execution on a dispatch queue.
|
||||
*
|
||||
* @discussion
|
||||
* See dispatch_async_and_wait() for details.
|
||||
*
|
||||
* @param queue
|
||||
* The target dispatch queue to which the function is submitted.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @param context
|
||||
* The application-defined context parameter to pass to the function.
|
||||
*
|
||||
* @param work
|
||||
* The application-defined function to invoke on the target queue. The first
|
||||
* parameter passed to this function is the context provided to
|
||||
* dispatch_async_and_wait_f().
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_async_and_wait_f(dispatch_queue_t queue,
|
||||
void *_Nullable context, dispatch_function_t work);
|
||||
|
||||
/*!
|
||||
* @function dispatch_barrier_async_and_wait
|
||||
*
|
||||
* @abstract
|
||||
* Submits a block for synchronous execution on a dispatch queue.
|
||||
*
|
||||
* @discussion
|
||||
* Submits a block to a dispatch queue like dispatch_async_and_wait(), but marks
|
||||
* that block as a barrier (relevant only on DISPATCH_QUEUE_CONCURRENT
|
||||
* queues).
|
||||
*
|
||||
* @param queue
|
||||
* The target dispatch queue to which the block is submitted.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @param work
|
||||
* The application-defined block to invoke on the target queue.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*/
|
||||
#ifdef __BLOCKS__
|
||||
API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL_ALL DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_barrier_async_and_wait(dispatch_queue_t queue,
|
||||
DISPATCH_NOESCAPE dispatch_block_t block);
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* @function dispatch_barrier_async_and_wait_f
|
||||
*
|
||||
* @abstract
|
||||
* Submits a function for synchronous execution on a dispatch queue.
|
||||
*
|
||||
* @discussion
|
||||
* Submits a function to a dispatch queue like dispatch_async_and_wait_f(), but
|
||||
* marks that function as a barrier (relevant only on DISPATCH_QUEUE_CONCURRENT
|
||||
* queues).
|
||||
*
|
||||
* @param queue
|
||||
* The target dispatch queue to which the function is submitted.
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*
|
||||
* @param context
|
||||
* The application-defined context parameter to pass to the function.
|
||||
*
|
||||
* @param work
|
||||
* The application-defined function to invoke on the target queue. The first
|
||||
* parameter passed to this function is the context provided to
|
||||
* dispatch_barrier_async_and_wait_f().
|
||||
* The result of passing NULL in this parameter is undefined.
|
||||
*/
|
||||
API_AVAILABLE(macos(10.14), ios(12.0), tvos(12.0), watchos(5.0))
|
||||
DISPATCH_EXPORT DISPATCH_NONNULL1 DISPATCH_NONNULL3 DISPATCH_NOTHROW
|
||||
void
|
||||
dispatch_barrier_async_and_wait_f(dispatch_queue_t queue,
|
||||
void *_Nullable context, dispatch_function_t work);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
DISPATCH_ASSUME_NONNULL_END
|
||||
|
||||
#endif
|
||||
26
Telegram/ThirdParty/dispatch/resolver/resolved.h
vendored
Normal file
26
Telegram/ThirdParty/dispatch/resolver/resolved.h
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2013 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/*
|
||||
* IMPORTANT: This header file describes INTERNAL interfaces to libdispatch
|
||||
* which are subject to change in future releases of Mac OS X. Any applications
|
||||
* relying on these interfaces WILL break.
|
||||
*/
|
||||
|
||||
20
Telegram/ThirdParty/dispatch/resolver/resolver.c
vendored
Normal file
20
Telegram/ThirdParty/dispatch/resolver/resolver.c
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2013 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
31
Telegram/ThirdParty/dispatch/resolver/resolver.h
vendored
Normal file
31
Telegram/ThirdParty/dispatch/resolver/resolver.h
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2010 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/*
|
||||
* IMPORTANT: This header file describes INTERNAL interfaces to libdispatch
|
||||
* which are subject to change in future releases of Mac OS X. Any applications
|
||||
* relying on these interfaces WILL break.
|
||||
*/
|
||||
|
||||
#ifndef __DISPATCH_RESOLVERS__
|
||||
#define __DISPATCH_RESOLVERS__
|
||||
|
||||
|
||||
#endif
|
||||
9
Telegram/ThirdParty/dispatch/src/.gitignore
vendored
Normal file
9
Telegram/ThirdParty/dispatch/src/.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
provider.h
|
||||
module.map
|
||||
module.build.map
|
||||
.libs
|
||||
*.lo
|
||||
*.la
|
||||
*.o
|
||||
*.swiftmodule
|
||||
*.swiftdoc
|
||||
73
Telegram/ThirdParty/dispatch/src/BlocksRuntime/Block.h
vendored
Normal file
73
Telegram/ThirdParty/dispatch/src/BlocksRuntime/Block.h
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
|
||||
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
//
|
||||
// See https://swift.org/LICENSE.txt for license information
|
||||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
//
|
||||
|
||||
|
||||
#ifndef _Block_H_
|
||||
#define _Block_H_
|
||||
|
||||
#if defined(_WIN32)
|
||||
# if defined(BlocksRuntime_STATIC)
|
||||
# define BLOCK_ABI
|
||||
# else
|
||||
# if defined(BlocksRuntime_EXPORTS)
|
||||
# define BLOCK_ABI __declspec(dllexport)
|
||||
# else
|
||||
# define BLOCK_ABI __declspec(dllimport)
|
||||
# endif
|
||||
# endif
|
||||
#else
|
||||
# define BLOCK_ABI __attribute__((__visibility__("default")))
|
||||
#endif
|
||||
|
||||
#if !defined(BLOCK_EXPORT)
|
||||
# if defined(__cplusplus)
|
||||
# define BLOCK_EXPORT extern "C" BLOCK_ABI
|
||||
# else
|
||||
# define BLOCK_EXPORT extern BLOCK_ABI
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Create a heap based copy of a Block or simply add a reference to an existing one.
|
||||
// This must be paired with Block_release to recover memory, even when running
|
||||
// under Objective-C Garbage Collection.
|
||||
BLOCK_EXPORT void *_Block_copy(const void *aBlock);
|
||||
|
||||
// Lose the reference, and if heap based and last reference, recover the memory
|
||||
BLOCK_EXPORT void _Block_release(const void *aBlock);
|
||||
|
||||
// Used by the compiler. Do not call this function yourself.
|
||||
BLOCK_EXPORT void _Block_object_assign(void *, const void *, const int);
|
||||
|
||||
// Used by the compiler. Do not call this function yourself.
|
||||
BLOCK_EXPORT void _Block_object_dispose(const void *, const int);
|
||||
|
||||
// Used by the compiler. Do not use these variables yourself.
|
||||
#if defined(_WIN32)
|
||||
extern void * _NSConcreteGlobalBlock[32];
|
||||
extern void * _NSConcreteStackBlock[32];
|
||||
#else
|
||||
BLOCK_EXPORT void * _NSConcreteGlobalBlock[32];
|
||||
BLOCK_EXPORT void * _NSConcreteStackBlock[32];
|
||||
#endif
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// Type correct macros
|
||||
|
||||
#define Block_copy(...) ((__typeof(__VA_ARGS__))_Block_copy((const void *)(__VA_ARGS__)))
|
||||
#define Block_release(...) _Block_release((const void *)(__VA_ARGS__))
|
||||
|
||||
|
||||
#endif
|
||||
264
Telegram/ThirdParty/dispatch/src/BlocksRuntime/Block_private.h
vendored
Normal file
264
Telegram/ThirdParty/dispatch/src/BlocksRuntime/Block_private.h
vendored
Normal file
@@ -0,0 +1,264 @@
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
|
||||
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
//
|
||||
// See https://swift.org/LICENSE.txt for license information
|
||||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
//
|
||||
|
||||
|
||||
#ifndef _BLOCK_PRIVATE_H_
|
||||
#define _BLOCK_PRIVATE_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "Block.h"
|
||||
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
// Values for Block_layout->flags to describe block objects
|
||||
enum {
|
||||
BLOCK_DEALLOCATING = (0x0001), // runtime
|
||||
BLOCK_REFCOUNT_MASK = (0xfffe), // runtime
|
||||
BLOCK_NEEDS_FREE = (1 << 24), // runtime
|
||||
BLOCK_HAS_COPY_DISPOSE = (1 << 25), // compiler
|
||||
BLOCK_HAS_CTOR = (1 << 26), // compiler: helpers have C++ code
|
||||
BLOCK_IS_GC = (1 << 27), // runtime
|
||||
BLOCK_IS_GLOBAL = (1 << 28), // compiler
|
||||
BLOCK_USE_STRET = (1 << 29), // compiler: undefined if !BLOCK_HAS_SIGNATURE
|
||||
BLOCK_HAS_SIGNATURE = (1 << 30), // compiler
|
||||
BLOCK_HAS_EXTENDED_LAYOUT=(1 << 31) // compiler
|
||||
};
|
||||
|
||||
#define BLOCK_DESCRIPTOR_1 1
|
||||
struct Block_descriptor_1 {
|
||||
unsigned long int reserved;
|
||||
unsigned long int size;
|
||||
};
|
||||
|
||||
#define BLOCK_DESCRIPTOR_2 1
|
||||
struct Block_descriptor_2 {
|
||||
// requires BLOCK_HAS_COPY_DISPOSE
|
||||
void (*copy)(void *dst, const void *src);
|
||||
void (*dispose)(const void *);
|
||||
};
|
||||
|
||||
#define BLOCK_DESCRIPTOR_3 1
|
||||
struct Block_descriptor_3 {
|
||||
// requires BLOCK_HAS_SIGNATURE
|
||||
const char *signature;
|
||||
const char *layout; // contents depend on BLOCK_HAS_EXTENDED_LAYOUT
|
||||
};
|
||||
|
||||
struct Block_layout {
|
||||
void *isa;
|
||||
volatile int32_t flags; // contains ref count
|
||||
int32_t reserved;
|
||||
void (*invoke)(void *, ...);
|
||||
struct Block_descriptor_1 *descriptor;
|
||||
// imported variables
|
||||
};
|
||||
|
||||
|
||||
// Values for Block_byref->flags to describe __block variables
|
||||
enum {
|
||||
// Byref refcount must use the same bits as Block_layout's refcount.
|
||||
// BLOCK_DEALLOCATING = (0x0001), // runtime
|
||||
// BLOCK_REFCOUNT_MASK = (0xfffe), // runtime
|
||||
|
||||
BLOCK_BYREF_LAYOUT_MASK = (0xf << 28), // compiler
|
||||
BLOCK_BYREF_LAYOUT_EXTENDED = ( 1 << 28), // compiler
|
||||
BLOCK_BYREF_LAYOUT_NON_OBJECT = ( 2 << 28), // compiler
|
||||
BLOCK_BYREF_LAYOUT_STRONG = ( 3 << 28), // compiler
|
||||
BLOCK_BYREF_LAYOUT_WEAK = ( 4 << 28), // compiler
|
||||
BLOCK_BYREF_LAYOUT_UNRETAINED = ( 5 << 28), // compiler
|
||||
|
||||
BLOCK_BYREF_IS_GC = ( 1 << 27), // runtime
|
||||
|
||||
BLOCK_BYREF_HAS_COPY_DISPOSE = ( 1 << 25), // compiler
|
||||
BLOCK_BYREF_NEEDS_FREE = ( 1 << 24), // runtime
|
||||
};
|
||||
|
||||
struct Block_byref {
|
||||
void *isa;
|
||||
struct Block_byref *forwarding;
|
||||
volatile int32_t flags; // contains ref count
|
||||
uint32_t size;
|
||||
};
|
||||
|
||||
struct Block_byref_2 {
|
||||
// requires BLOCK_BYREF_HAS_COPY_DISPOSE
|
||||
void (*byref_keep)(struct Block_byref *dst, struct Block_byref *src);
|
||||
void (*byref_destroy)(struct Block_byref *);
|
||||
};
|
||||
|
||||
struct Block_byref_3 {
|
||||
// requires BLOCK_BYREF_LAYOUT_EXTENDED
|
||||
const char *layout;
|
||||
};
|
||||
|
||||
|
||||
// Extended layout encoding.
|
||||
|
||||
// Values for Block_descriptor_3->layout with BLOCK_HAS_EXTENDED_LAYOUT
|
||||
// and for Block_byref_3->layout with BLOCK_BYREF_LAYOUT_EXTENDED
|
||||
|
||||
// If the layout field is less than 0x1000, then it is a compact encoding
|
||||
// of the form 0xXYZ: X strong pointers, then Y byref pointers,
|
||||
// then Z weak pointers.
|
||||
|
||||
// If the layout field is 0x1000 or greater, it points to a
|
||||
// string of layout bytes. Each byte is of the form 0xPN.
|
||||
// Operator P is from the list below. Value N is a parameter for the operator.
|
||||
// Byte 0x00 terminates the layout; remaining block data is non-pointer bytes.
|
||||
|
||||
enum {
|
||||
BLOCK_LAYOUT_ESCAPE = 0, // N=0 halt, rest is non-pointer. N!=0 reserved.
|
||||
BLOCK_LAYOUT_NON_OBJECT_BYTES = 1, // N bytes non-objects
|
||||
BLOCK_LAYOUT_NON_OBJECT_WORDS = 2, // N words non-objects
|
||||
BLOCK_LAYOUT_STRONG = 3, // N words strong pointers
|
||||
BLOCK_LAYOUT_BYREF = 4, // N words byref pointers
|
||||
BLOCK_LAYOUT_WEAK = 5, // N words weak pointers
|
||||
BLOCK_LAYOUT_UNRETAINED = 6, // N words unretained pointers
|
||||
BLOCK_LAYOUT_UNKNOWN_WORDS_7 = 7, // N words, reserved
|
||||
BLOCK_LAYOUT_UNKNOWN_WORDS_8 = 8, // N words, reserved
|
||||
BLOCK_LAYOUT_UNKNOWN_WORDS_9 = 9, // N words, reserved
|
||||
BLOCK_LAYOUT_UNKNOWN_WORDS_A = 0xA, // N words, reserved
|
||||
BLOCK_LAYOUT_UNUSED_B = 0xB, // unspecified, reserved
|
||||
BLOCK_LAYOUT_UNUSED_C = 0xC, // unspecified, reserved
|
||||
BLOCK_LAYOUT_UNUSED_D = 0xD, // unspecified, reserved
|
||||
BLOCK_LAYOUT_UNUSED_E = 0xE, // unspecified, reserved
|
||||
BLOCK_LAYOUT_UNUSED_F = 0xF, // unspecified, reserved
|
||||
};
|
||||
|
||||
|
||||
// Runtime support functions used by compiler when generating copy/dispose helpers
|
||||
|
||||
// Values for _Block_object_assign() and _Block_object_dispose() parameters
|
||||
enum {
|
||||
// see function implementation for a more complete description of these fields and combinations
|
||||
BLOCK_FIELD_IS_OBJECT = 3, // id, NSObject, __attribute__((NSObject)), block, ...
|
||||
BLOCK_FIELD_IS_BLOCK = 7, // a block variable
|
||||
BLOCK_FIELD_IS_BYREF = 8, // the on stack structure holding the __block variable
|
||||
BLOCK_FIELD_IS_WEAK = 16, // declared __weak, only used in byref copy helpers
|
||||
BLOCK_BYREF_CALLER = 128, // called from __block (byref) copy/dispose support routines.
|
||||
};
|
||||
|
||||
enum {
|
||||
BLOCK_ALL_COPY_DISPOSE_FLAGS =
|
||||
BLOCK_FIELD_IS_OBJECT | BLOCK_FIELD_IS_BLOCK | BLOCK_FIELD_IS_BYREF |
|
||||
BLOCK_FIELD_IS_WEAK | BLOCK_BYREF_CALLER
|
||||
};
|
||||
|
||||
// Runtime entry point called by compiler when assigning objects inside copy helper routines
|
||||
BLOCK_EXPORT void _Block_object_assign(void *destAddr, const void *object, const int flags);
|
||||
// BLOCK_FIELD_IS_BYREF is only used from within block copy helpers
|
||||
|
||||
|
||||
// runtime entry point called by the compiler when disposing of objects inside dispose helper routine
|
||||
BLOCK_EXPORT void _Block_object_dispose(const void *object, const int flags);
|
||||
|
||||
|
||||
// Other support functions
|
||||
|
||||
// runtime entry to get total size of a closure
|
||||
BLOCK_EXPORT size_t Block_size(void *aBlock);
|
||||
|
||||
// indicates whether block was compiled with compiler that sets the ABI related metadata bits
|
||||
BLOCK_EXPORT bool _Block_has_signature(void *aBlock);
|
||||
|
||||
// returns TRUE if return value of block is on the stack, FALSE otherwise
|
||||
BLOCK_EXPORT bool _Block_use_stret(void *aBlock);
|
||||
|
||||
// Returns a string describing the block's parameter and return types.
|
||||
// The encoding scheme is the same as Objective-C @encode.
|
||||
// Returns NULL for blocks compiled with some compilers.
|
||||
BLOCK_EXPORT const char * _Block_signature(void *aBlock);
|
||||
|
||||
// Returns a string describing the block's GC layout.
|
||||
// This uses the GC skip/scan encoding.
|
||||
// May return NULL.
|
||||
BLOCK_EXPORT const char * _Block_layout(void *aBlock);
|
||||
|
||||
// Returns a string describing the block's layout.
|
||||
// This uses the "extended layout" form described above.
|
||||
// May return NULL.
|
||||
BLOCK_EXPORT const char * _Block_extended_layout(void *aBlock);
|
||||
|
||||
// Callable only from the ARR weak subsystem while in exclusion zone
|
||||
BLOCK_EXPORT bool _Block_tryRetain(const void *aBlock);
|
||||
|
||||
// Callable only from the ARR weak subsystem while in exclusion zone
|
||||
BLOCK_EXPORT bool _Block_isDeallocating(const void *aBlock);
|
||||
|
||||
|
||||
// the raw data space for runtime classes for blocks
|
||||
// class+meta used for stack, malloc, and collectable based blocks
|
||||
BLOCK_EXPORT void * _NSConcreteMallocBlock[32];
|
||||
BLOCK_EXPORT void * _NSConcreteAutoBlock[32];
|
||||
BLOCK_EXPORT void * _NSConcreteFinalizingBlock[32];
|
||||
BLOCK_EXPORT void * _NSConcreteWeakBlockVariable[32];
|
||||
// declared in Block.h
|
||||
// BLOCK_EXPORT void * _NSConcreteGlobalBlock[32];
|
||||
// BLOCK_EXPORT void * _NSConcreteStackBlock[32];
|
||||
|
||||
|
||||
// the intercept routines that must be used under GC
|
||||
BLOCK_EXPORT void _Block_use_GC( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject),
|
||||
void (*setHasRefcount)(const void *, const bool),
|
||||
void (*gc_assign_strong)(void *, void **),
|
||||
void (*gc_assign_weak)(const void *, void *),
|
||||
void (*gc_memmove)(void *, void *, unsigned long));
|
||||
|
||||
// earlier version, now simply transitional
|
||||
BLOCK_EXPORT void _Block_use_GC5( void *(*alloc)(const unsigned long, const bool isOne, const bool isObject),
|
||||
void (*setHasRefcount)(const void *, const bool),
|
||||
void (*gc_assign_strong)(void *, void **),
|
||||
void (*gc_assign_weak)(const void *, void *));
|
||||
|
||||
BLOCK_EXPORT void _Block_use_RR( void (*retain)(const void *),
|
||||
void (*release)(const void *));
|
||||
|
||||
struct Block_callbacks_RR {
|
||||
size_t size; // size == sizeof(struct Block_callbacks_RR)
|
||||
void (*retain)(const void *);
|
||||
void (*release)(const void *);
|
||||
void (*destructInstance)(const void *);
|
||||
};
|
||||
typedef struct Block_callbacks_RR Block_callbacks_RR;
|
||||
|
||||
BLOCK_EXPORT void _Block_use_RR2(const Block_callbacks_RR *callbacks);
|
||||
|
||||
// make a collectable GC heap based Block. Not useful under non-GC.
|
||||
BLOCK_EXPORT void *_Block_copy_collectable(const void *aBlock);
|
||||
|
||||
// thread-unsafe diagnostic
|
||||
BLOCK_EXPORT const char *_Block_dump(const void *block);
|
||||
|
||||
|
||||
// Obsolete
|
||||
|
||||
// first layout
|
||||
struct Block_basic {
|
||||
void *isa;
|
||||
int Block_flags; // int32_t
|
||||
int Block_size; // XXX should be packed into Block_flags
|
||||
void (*Block_invoke)(void *);
|
||||
void (*Block_copy)(void *dst, void *src); // iff BLOCK_HAS_COPY_DISPOSE
|
||||
void (*Block_dispose)(void *); // iff BLOCK_HAS_COPY_DISPOSE
|
||||
//long params[0]; // where const imports, __block storage references, etc. get laid down
|
||||
} __attribute__((deprecated));
|
||||
|
||||
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
4
Telegram/ThirdParty/dispatch/src/BlocksRuntime/BlocksRuntime.def
vendored
Normal file
4
Telegram/ThirdParty/dispatch/src/BlocksRuntime/BlocksRuntime.def
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
LIBRARY BlocksRuntime
|
||||
EXPORTS
|
||||
_NSConcreteGlobalBlock CONSTANT
|
||||
_NSConcreteStackBlock CONSTANT
|
||||
42
Telegram/ThirdParty/dispatch/src/BlocksRuntime/CMakeLists.txt
vendored
Normal file
42
Telegram/ThirdParty/dispatch/src/BlocksRuntime/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
|
||||
add_library(BlocksRuntime
|
||||
data.c
|
||||
runtime.c)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL Windows)
|
||||
target_sources(BlocksRuntime PRIVATE
|
||||
BlocksRuntime.def)
|
||||
|
||||
if(NOT BUILD_SHARED_LIBS)
|
||||
target_compile_definitions(BlocksRuntime PRIVATE
|
||||
BlocksRuntime_STATIC)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_include_directories(BlocksRuntime PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR})
|
||||
if(HAVE_OBJC AND CMAKE_DL_LIBS)
|
||||
target_link_libraries(BlocksRuntime PUBLIC
|
||||
${CMAKE_DL_LIBS})
|
||||
endif()
|
||||
|
||||
set_target_properties(BlocksRuntime PROPERTIES
|
||||
POSITION_INDEPENDENT_CODE TRUE)
|
||||
|
||||
if(LINKER_SUPPORTS_BUILD_ID)
|
||||
target_link_options(BlocksRuntime PRIVATE "LINKER:--build-id=sha1")
|
||||
endif()
|
||||
|
||||
add_library(BlocksRuntime::BlocksRuntime ALIAS BlocksRuntime)
|
||||
|
||||
install(FILES Block.h
|
||||
DESTINATION ${INSTALL_BLOCK_HEADERS_DIR})
|
||||
if(INSTALL_PRIVATE_HEADERS)
|
||||
install(FILES Block_private.h
|
||||
DESTINATION ${INSTALL_BLOCK_HEADERS_DIR})
|
||||
endif()
|
||||
set_property(GLOBAL APPEND PROPERTY DISPATCH_EXPORTS BlocksRuntime)
|
||||
install(TARGETS BlocksRuntime
|
||||
EXPORT dispatchExports
|
||||
ARCHIVE DESTINATION ${INSTALL_TARGET_DIR}
|
||||
LIBRARY DESTINATION ${INSTALL_TARGET_DIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
30
Telegram/ThirdParty/dispatch/src/BlocksRuntime/data.c
vendored
Normal file
30
Telegram/ThirdParty/dispatch/src/BlocksRuntime/data.c
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
|
||||
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
//
|
||||
// See https://swift.org/LICENSE.txt for license information
|
||||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
//
|
||||
|
||||
/********************
|
||||
NSBlock support
|
||||
|
||||
We allocate space and export a symbol to be used as the Class for the on-stack and malloc'ed copies until ObjC arrives on the scene. These data areas are set up by Foundation to link in as real classes post facto.
|
||||
|
||||
We keep these in a separate file so that we can include the runtime code in test subprojects but not include the data so that compiled code that sees the data in libSystem doesn't get confused by a second copy. Somehow these don't get unified in a common block.
|
||||
**********************/
|
||||
#include "Block.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
void * _NSConcreteStackBlock[32] = { 0 };
|
||||
void * _NSConcreteGlobalBlock[32] = { 0 };
|
||||
#else
|
||||
BLOCK_ABI void * _NSConcreteStackBlock[32] = { 0 };
|
||||
BLOCK_ABI void * _NSConcreteGlobalBlock[32] = { 0 };
|
||||
#endif
|
||||
|
||||
BLOCK_ABI void * _NSConcreteMallocBlock[32] = { 0 };
|
||||
BLOCK_ABI void * _NSConcreteAutoBlock[32] = { 0 };
|
||||
BLOCK_ABI void * _NSConcreteFinalizingBlock[32] = { 0 };
|
||||
BLOCK_ABI void * _NSConcreteWeakBlockVariable[32] = { 0 };
|
||||
760
Telegram/ThirdParty/dispatch/src/BlocksRuntime/runtime.c
vendored
Normal file
760
Telegram/ThirdParty/dispatch/src/BlocksRuntime/runtime.c
vendored
Normal file
@@ -0,0 +1,760 @@
|
||||
// This source file is part of the Swift.org open source project
|
||||
//
|
||||
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
|
||||
// Licensed under Apache License v2.0 with Runtime Library Exception
|
||||
//
|
||||
// See https://swift.org/LICENSE.txt for license information
|
||||
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
||||
//
|
||||
|
||||
#include "Block_private.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#if HAVE_OBJC
|
||||
#define __USE_GNU
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
#if __has_include(<os/assumes.h>)
|
||||
#include <os/assumes.h>
|
||||
#else
|
||||
#include <assert.h>
|
||||
#endif
|
||||
#ifndef os_assumes
|
||||
#define os_assumes(_x) _x
|
||||
#endif
|
||||
#ifndef os_assert
|
||||
#define os_assert(_x) assert(_x)
|
||||
#endif
|
||||
|
||||
#if !defined(__has_builtin)
|
||||
#define __has_builtin(builtin) 0
|
||||
#endif
|
||||
|
||||
#if __has_builtin(__sync_bool_compare_and_swap)
|
||||
#define OSAtomicCompareAndSwapInt(_Old, _New, _Ptr) \
|
||||
__sync_bool_compare_and_swap(_Ptr, _Old, _New)
|
||||
#else
|
||||
#define _CRT_SECURE_NO_WARNINGS 1
|
||||
#include <Windows.h>
|
||||
static __inline bool OSAtomicCompareAndSwapInt(int oldi, int newi,
|
||||
int volatile *dst) {
|
||||
// fixme barrier is overkill -- see objc-os.h
|
||||
int original = InterlockedCompareExchange((LONG volatile *)dst, newi, oldi);
|
||||
return (original == oldi);
|
||||
}
|
||||
#endif
|
||||
|
||||
/***********************
|
||||
Globals
|
||||
************************/
|
||||
|
||||
#if HAVE_OBJC
|
||||
static void *_Block_copy_class = _NSConcreteMallocBlock;
|
||||
static void *_Block_copy_finalizing_class = _NSConcreteMallocBlock;
|
||||
static int _Block_copy_flag = BLOCK_NEEDS_FREE;
|
||||
#endif
|
||||
static int _Byref_flag_initial_value = BLOCK_BYREF_NEEDS_FREE | 4; // logical 2
|
||||
|
||||
static bool isGC = false;
|
||||
|
||||
/*******************************************************************************
|
||||
Internal Utilities
|
||||
********************************************************************************/
|
||||
|
||||
|
||||
static int32_t latching_incr_int(volatile int32_t *where) {
|
||||
while (1) {
|
||||
int32_t old_value = *where;
|
||||
if ((old_value & BLOCK_REFCOUNT_MASK) == BLOCK_REFCOUNT_MASK) {
|
||||
return BLOCK_REFCOUNT_MASK;
|
||||
}
|
||||
if (OSAtomicCompareAndSwapInt(old_value, old_value+2, where)) {
|
||||
return old_value+2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool latching_incr_int_not_deallocating(volatile int32_t *where) {
|
||||
while (1) {
|
||||
int32_t old_value = *where;
|
||||
if (old_value & BLOCK_DEALLOCATING) {
|
||||
// if deallocating we can't do this
|
||||
return false;
|
||||
}
|
||||
if ((old_value & BLOCK_REFCOUNT_MASK) == BLOCK_REFCOUNT_MASK) {
|
||||
// if latched, we're leaking this block, and we succeed
|
||||
return true;
|
||||
}
|
||||
if (OSAtomicCompareAndSwapInt(old_value, old_value+2, where)) {
|
||||
// otherwise, we must store a new retained value without the deallocating bit set
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// return should_deallocate?
|
||||
static bool latching_decr_int_should_deallocate(volatile int32_t *where) {
|
||||
while (1) {
|
||||
int32_t old_value = *where;
|
||||
if ((old_value & BLOCK_REFCOUNT_MASK) == BLOCK_REFCOUNT_MASK) {
|
||||
return false; // latched high
|
||||
}
|
||||
if ((old_value & BLOCK_REFCOUNT_MASK) == 0) {
|
||||
return false; // underflow, latch low
|
||||
}
|
||||
int32_t new_value = old_value - 2;
|
||||
bool result = false;
|
||||
if ((old_value & (BLOCK_REFCOUNT_MASK|BLOCK_DEALLOCATING)) == 2) {
|
||||
new_value = old_value - 1;
|
||||
result = true;
|
||||
}
|
||||
if (OSAtomicCompareAndSwapInt(old_value, new_value, where)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// hit zero?
|
||||
static bool latching_decr_int_now_zero(volatile int32_t *where) {
|
||||
while (1) {
|
||||
int32_t old_value = *where;
|
||||
if ((old_value & BLOCK_REFCOUNT_MASK) == BLOCK_REFCOUNT_MASK) {
|
||||
return false; // latched high
|
||||
}
|
||||
if ((old_value & BLOCK_REFCOUNT_MASK) == 0) {
|
||||
return false; // underflow, latch low
|
||||
}
|
||||
int32_t new_value = old_value - 2;
|
||||
if (OSAtomicCompareAndSwapInt(old_value, new_value, where)) {
|
||||
return (new_value & BLOCK_REFCOUNT_MASK) == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************
|
||||
GC support stub routines
|
||||
************************/
|
||||
#if !defined(_MSC_VER) || defined(__clang__)
|
||||
#pragma mark GC Support Routines
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static void *_Block_alloc_default(size_t size, const bool initialCountIsOne, const bool isObject) {
|
||||
(void)initialCountIsOne;
|
||||
(void)isObject;
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
static void _Block_assign_default(void *value, void **destptr) {
|
||||
*destptr = value;
|
||||
}
|
||||
|
||||
static void _Block_setHasRefcount_default(const void *ptr, const bool hasRefcount) {
|
||||
(void)ptr;
|
||||
(void)hasRefcount;
|
||||
}
|
||||
|
||||
#if HAVE_OBJC
|
||||
static void _Block_do_nothing(const void *aBlock) { }
|
||||
#endif
|
||||
|
||||
static void _Block_retain_object_default(const void *ptr) {
|
||||
(void)ptr;
|
||||
}
|
||||
|
||||
static void _Block_release_object_default(const void *ptr) {
|
||||
(void)ptr;
|
||||
}
|
||||
|
||||
static void _Block_assign_weak_default(const void *ptr, void *dest) {
|
||||
#if !defined(_WIN32)
|
||||
*(long *)dest = (long)ptr;
|
||||
#else
|
||||
*(void **)dest = (void *)ptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void _Block_memmove_default(void *dst, void *src, unsigned long size) {
|
||||
memmove(dst, src, (size_t)size);
|
||||
}
|
||||
|
||||
#if HAVE_OBJC
|
||||
static void _Block_memmove_gc_broken(void *dest, void *src, unsigned long size) {
|
||||
void **destp = (void **)dest;
|
||||
void **srcp = (void **)src;
|
||||
while (size) {
|
||||
_Block_assign_default(*srcp, destp);
|
||||
destp++;
|
||||
srcp++;
|
||||
size -= sizeof(void *);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void _Block_destructInstance_default(const void *aBlock) {
|
||||
(void)aBlock;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
GC support callout functions - initially set to stub routines
|
||||
***************************************************************************/
|
||||
|
||||
static void *(*_Block_allocator)(size_t, const bool isOne, const bool isObject) = _Block_alloc_default;
|
||||
static void (*_Block_deallocator)(const void *) = (void (*)(const void *))free;
|
||||
static void (*_Block_assign)(void *value, void **destptr) = _Block_assign_default;
|
||||
static void (*_Block_setHasRefcount)(const void *ptr, const bool hasRefcount) = _Block_setHasRefcount_default;
|
||||
static void (*_Block_retain_object)(const void *ptr) = _Block_retain_object_default;
|
||||
static void (*_Block_release_object)(const void *ptr) = _Block_release_object_default;
|
||||
static void (*_Block_assign_weak)(const void *dest, void *ptr) = _Block_assign_weak_default;
|
||||
static void (*_Block_memmove)(void *dest, void *src, unsigned long size) = _Block_memmove_default;
|
||||
static void (*_Block_destructInstance) (const void *aBlock) = _Block_destructInstance_default;
|
||||
|
||||
|
||||
#if HAVE_OBJC
|
||||
/**************************************************************************
|
||||
GC support SPI functions - called from ObjC runtime and CoreFoundation
|
||||
***************************************************************************/
|
||||
|
||||
// Public SPI
|
||||
// Called from objc-auto to turn on GC.
|
||||
// version 3, 4 arg, but changed 1st arg
|
||||
void _Block_use_GC( void *(*alloc)(size_t, const bool isOne, const bool isObject),
|
||||
void (*setHasRefcount)(const void *, const bool),
|
||||
void (*gc_assign)(void *, void **),
|
||||
void (*gc_assign_weak)(const void *, void *),
|
||||
void (*gc_memmove)(void *, void *, unsigned long)) {
|
||||
|
||||
isGC = true;
|
||||
_Block_allocator = alloc;
|
||||
_Block_deallocator = _Block_do_nothing;
|
||||
_Block_assign = gc_assign;
|
||||
_Block_copy_flag = BLOCK_IS_GC;
|
||||
_Block_copy_class = _NSConcreteAutoBlock;
|
||||
// blocks with ctors & dtors need to have the dtor run from a class with a finalizer
|
||||
_Block_copy_finalizing_class = _NSConcreteFinalizingBlock;
|
||||
_Block_setHasRefcount = setHasRefcount;
|
||||
_Byref_flag_initial_value = BLOCK_BYREF_IS_GC; // no refcount
|
||||
_Block_retain_object = _Block_do_nothing;
|
||||
_Block_release_object = _Block_do_nothing;
|
||||
_Block_assign_weak = gc_assign_weak;
|
||||
_Block_memmove = gc_memmove;
|
||||
}
|
||||
|
||||
// transitional
|
||||
void _Block_use_GC5( void *(*alloc)(size_t, const bool isOne, const bool isObject),
|
||||
void (*setHasRefcount)(const void *, const bool),
|
||||
void (*gc_assign)(void *, void **),
|
||||
void (*gc_assign_weak)(const void *, void *)) {
|
||||
// until objc calls _Block_use_GC it will call us; supply a broken internal memmove implementation until then
|
||||
_Block_use_GC(alloc, setHasRefcount, gc_assign, gc_assign_weak, _Block_memmove_gc_broken);
|
||||
}
|
||||
|
||||
|
||||
// Called from objc-auto to alternatively turn on retain/release.
|
||||
// Prior to this the only "object" support we can provide is for those
|
||||
// super special objects that live in libSystem, namely dispatch queues.
|
||||
// Blocks and Block_byrefs have their own special entry points.
|
||||
BLOCK_EXPORT
|
||||
void _Block_use_RR( void (*retain)(const void *),
|
||||
void (*release)(const void *)) {
|
||||
_Block_retain_object = retain;
|
||||
_Block_release_object = release;
|
||||
_Block_destructInstance = dlsym(RTLD_DEFAULT, "objc_destructInstance");
|
||||
}
|
||||
#endif // HAVE_OBJC
|
||||
|
||||
// Called from CF to indicate MRR. Newer version uses a versioned structure, so we can add more functions
|
||||
// without defining a new entry point.
|
||||
BLOCK_EXPORT
|
||||
void _Block_use_RR2(const Block_callbacks_RR *callbacks) {
|
||||
_Block_retain_object = callbacks->retain;
|
||||
_Block_release_object = callbacks->release;
|
||||
_Block_destructInstance = callbacks->destructInstance;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Accessors for block descriptor fields
|
||||
*****************************************************************************/
|
||||
#if 0
|
||||
static struct Block_descriptor_1 * _Block_descriptor_1(struct Block_layout *aBlock)
|
||||
{
|
||||
return aBlock->descriptor;
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct Block_descriptor_2 * _Block_descriptor_2(struct Block_layout *aBlock)
|
||||
{
|
||||
if (! (aBlock->flags & BLOCK_HAS_COPY_DISPOSE)) return NULL;
|
||||
uint8_t *desc = (uint8_t *)aBlock->descriptor;
|
||||
desc += sizeof(struct Block_descriptor_1);
|
||||
return (struct Block_descriptor_2 *)desc;
|
||||
}
|
||||
|
||||
static struct Block_descriptor_3 * _Block_descriptor_3(struct Block_layout *aBlock)
|
||||
{
|
||||
if (! (aBlock->flags & BLOCK_HAS_SIGNATURE)) return NULL;
|
||||
uint8_t *desc = (uint8_t *)aBlock->descriptor;
|
||||
desc += sizeof(struct Block_descriptor_1);
|
||||
if (aBlock->flags & BLOCK_HAS_COPY_DISPOSE) {
|
||||
desc += sizeof(struct Block_descriptor_2);
|
||||
}
|
||||
return (struct Block_descriptor_3 *)desc;
|
||||
}
|
||||
|
||||
static __inline bool _Block_has_layout(struct Block_layout *aBlock) {
|
||||
if (! (aBlock->flags & BLOCK_HAS_SIGNATURE)) return false;
|
||||
uint8_t *desc = (uint8_t *)aBlock->descriptor;
|
||||
desc += sizeof(struct Block_descriptor_1);
|
||||
if (aBlock->flags & BLOCK_HAS_COPY_DISPOSE) {
|
||||
desc += sizeof(struct Block_descriptor_2);
|
||||
}
|
||||
return ((struct Block_descriptor_3 *)desc)->layout != NULL;
|
||||
}
|
||||
|
||||
static void _Block_call_copy_helper(void *result, struct Block_layout *aBlock)
|
||||
{
|
||||
struct Block_descriptor_2 *desc = _Block_descriptor_2(aBlock);
|
||||
if (!desc) return;
|
||||
|
||||
(*desc->copy)(result, aBlock); // do fixup
|
||||
}
|
||||
|
||||
static void _Block_call_dispose_helper(struct Block_layout *aBlock)
|
||||
{
|
||||
struct Block_descriptor_2 *desc = _Block_descriptor_2(aBlock);
|
||||
if (!desc) return;
|
||||
|
||||
(*desc->dispose)(aBlock);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
Internal Support routines for copying
|
||||
********************************************************************************/
|
||||
|
||||
#if !defined(_MSC_VER) || defined(__clang__)
|
||||
#pragma mark Copy/Release support
|
||||
#endif
|
||||
|
||||
// Copy, or bump refcount, of a block. If really copying, call the copy helper if present.
|
||||
static void *_Block_copy_internal(const void *arg, const bool wantsOne) {
|
||||
struct Block_layout *aBlock;
|
||||
|
||||
if (!arg) return NULL;
|
||||
|
||||
|
||||
// The following would be better done as a switch statement
|
||||
aBlock = (struct Block_layout *)arg;
|
||||
if (aBlock->flags & BLOCK_NEEDS_FREE) {
|
||||
// latches on high
|
||||
latching_incr_int(&aBlock->flags);
|
||||
return aBlock;
|
||||
}
|
||||
else if (aBlock->flags & BLOCK_IS_GC) {
|
||||
// GC refcounting is expensive so do most refcounting here.
|
||||
if (wantsOne && ((latching_incr_int(&aBlock->flags) & BLOCK_REFCOUNT_MASK) == 2)) {
|
||||
// Tell collector to hang on this - it will bump the GC refcount version
|
||||
_Block_setHasRefcount(aBlock, true);
|
||||
}
|
||||
return aBlock;
|
||||
}
|
||||
else if (aBlock->flags & BLOCK_IS_GLOBAL) {
|
||||
return aBlock;
|
||||
}
|
||||
|
||||
// Its a stack block. Make a copy.
|
||||
if (!isGC) {
|
||||
struct Block_layout *result = malloc(aBlock->descriptor->size);
|
||||
if (!result) return NULL;
|
||||
memmove(result, aBlock, aBlock->descriptor->size); // bitcopy first
|
||||
// reset refcount
|
||||
result->flags &= ~(BLOCK_REFCOUNT_MASK|BLOCK_DEALLOCATING); // XXX not needed
|
||||
result->flags |= BLOCK_NEEDS_FREE | 2; // logical refcount 1
|
||||
result->isa = _NSConcreteMallocBlock;
|
||||
_Block_call_copy_helper(result, aBlock);
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
// Under GC want allocation with refcount 1 so we ask for "true" if wantsOne
|
||||
// This allows the copy helper routines to make non-refcounted block copies under GC
|
||||
int32_t flags = aBlock->flags;
|
||||
bool hasCTOR = (flags & BLOCK_HAS_CTOR) != 0;
|
||||
struct Block_layout *result = _Block_allocator(aBlock->descriptor->size, wantsOne, hasCTOR || _Block_has_layout(aBlock));
|
||||
if (!result) return NULL;
|
||||
memmove(result, aBlock, aBlock->descriptor->size); // bitcopy first
|
||||
// reset refcount
|
||||
// if we copy a malloc block to a GC block then we need to clear NEEDS_FREE.
|
||||
flags &= ~(BLOCK_NEEDS_FREE|BLOCK_REFCOUNT_MASK|BLOCK_DEALLOCATING); // XXX not needed
|
||||
if (wantsOne)
|
||||
flags |= BLOCK_IS_GC | 2;
|
||||
else
|
||||
flags |= BLOCK_IS_GC;
|
||||
result->flags = flags;
|
||||
_Block_call_copy_helper(result, aBlock);
|
||||
if (hasCTOR) {
|
||||
result->isa = _NSConcreteFinalizingBlock;
|
||||
}
|
||||
else {
|
||||
result->isa = _NSConcreteAutoBlock;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Runtime entry points for maintaining the sharing knowledge of byref data blocks.
|
||||
|
||||
// A closure has been copied and its fixup routine is asking us to fix up the reference to the shared byref data
|
||||
// Closures that aren't copied must still work, so everyone always accesses variables after dereferencing the forwarding ptr.
|
||||
// We ask if the byref pointer that we know about has already been copied to the heap, and if so, increment it.
|
||||
// Otherwise we need to copy it and update the stack forwarding pointer
|
||||
static void _Block_byref_assign_copy(void *dest, const void *arg, const int flags) {
|
||||
struct Block_byref **destp = (struct Block_byref **)dest;
|
||||
struct Block_byref *src = (struct Block_byref *)arg;
|
||||
|
||||
if (src->forwarding->flags & BLOCK_BYREF_IS_GC) {
|
||||
; // don't need to do any more work
|
||||
}
|
||||
else if ((src->forwarding->flags & BLOCK_REFCOUNT_MASK) == 0) {
|
||||
// src points to stack
|
||||
bool isWeak = ((flags & (BLOCK_FIELD_IS_BYREF|BLOCK_FIELD_IS_WEAK)) == (BLOCK_FIELD_IS_BYREF|BLOCK_FIELD_IS_WEAK));
|
||||
// if its weak ask for an object (only matters under GC)
|
||||
struct Block_byref *copy = (struct Block_byref *)_Block_allocator(src->size, false, isWeak);
|
||||
copy->flags = src->flags | _Byref_flag_initial_value; // non-GC one for caller, one for stack
|
||||
copy->forwarding = copy; // patch heap copy to point to itself (skip write-barrier)
|
||||
src->forwarding = copy; // patch stack to point to heap copy
|
||||
copy->size = src->size;
|
||||
if (isWeak) {
|
||||
copy->isa = &_NSConcreteWeakBlockVariable; // mark isa field so it gets weak scanning
|
||||
}
|
||||
if (src->flags & BLOCK_BYREF_HAS_COPY_DISPOSE) {
|
||||
// Trust copy helper to copy everything of interest
|
||||
// If more than one field shows up in a byref block this is wrong XXX
|
||||
struct Block_byref_2 *src2 = (struct Block_byref_2 *)(src+1);
|
||||
struct Block_byref_2 *copy2 = (struct Block_byref_2 *)(copy+1);
|
||||
copy2->byref_keep = src2->byref_keep;
|
||||
copy2->byref_destroy = src2->byref_destroy;
|
||||
|
||||
if (src->flags & BLOCK_BYREF_LAYOUT_EXTENDED) {
|
||||
struct Block_byref_3 *src3 = (struct Block_byref_3 *)(src2+1);
|
||||
struct Block_byref_3 *copy3 = (struct Block_byref_3*)(copy2+1);
|
||||
copy3->layout = src3->layout;
|
||||
}
|
||||
|
||||
(*src2->byref_keep)(copy, src);
|
||||
}
|
||||
else {
|
||||
// just bits. Blast 'em using _Block_memmove in case they're __strong
|
||||
// This copy includes Block_byref_3, if any.
|
||||
_Block_memmove(copy+1, src+1,
|
||||
src->size - sizeof(struct Block_byref));
|
||||
}
|
||||
}
|
||||
// already copied to heap
|
||||
else if ((src->forwarding->flags & BLOCK_BYREF_NEEDS_FREE) == BLOCK_BYREF_NEEDS_FREE) {
|
||||
latching_incr_int(&src->forwarding->flags);
|
||||
}
|
||||
// assign byref data block pointer into new Block
|
||||
_Block_assign(src->forwarding, (void **)destp);
|
||||
}
|
||||
|
||||
// Old compiler SPI
|
||||
static void _Block_byref_release(const void *arg) {
|
||||
struct Block_byref *byref = (struct Block_byref *)arg;
|
||||
|
||||
// dereference the forwarding pointer since the compiler isn't doing this anymore (ever?)
|
||||
byref = byref->forwarding;
|
||||
|
||||
// To support C++ destructors under GC we arrange for there to be a finalizer for this
|
||||
// by using an isa that directs the code to a finalizer that calls the byref_destroy method.
|
||||
if ((byref->flags & BLOCK_BYREF_NEEDS_FREE) == 0) {
|
||||
return; // stack or GC or global
|
||||
}
|
||||
os_assert(byref->flags & BLOCK_REFCOUNT_MASK);
|
||||
if (latching_decr_int_should_deallocate(&byref->flags)) {
|
||||
if (byref->flags & BLOCK_BYREF_HAS_COPY_DISPOSE) {
|
||||
struct Block_byref_2 *byref2 = (struct Block_byref_2 *)(byref+1);
|
||||
(*byref2->byref_destroy)(byref);
|
||||
}
|
||||
_Block_deallocator((struct Block_layout *)byref);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************************
|
||||
*
|
||||
* API supporting SPI
|
||||
* _Block_copy, _Block_release, and (old) _Block_destroy
|
||||
*
|
||||
***********************************************************/
|
||||
|
||||
#if !defined(_MSC_VER) || defined(__clang__)
|
||||
#pragma mark SPI/API
|
||||
#endif
|
||||
|
||||
BLOCK_EXPORT
|
||||
void *_Block_copy(const void *arg) {
|
||||
return _Block_copy_internal(arg, true);
|
||||
}
|
||||
|
||||
|
||||
// API entry point to release a copied Block
|
||||
BLOCK_EXPORT
|
||||
void _Block_release(const void *arg) {
|
||||
struct Block_layout *aBlock = (struct Block_layout *)arg;
|
||||
if (!aBlock
|
||||
|| (aBlock->flags & BLOCK_IS_GLOBAL)
|
||||
|| ((aBlock->flags & (BLOCK_IS_GC|BLOCK_NEEDS_FREE)) == 0)
|
||||
) return;
|
||||
if (aBlock->flags & BLOCK_IS_GC) {
|
||||
if (latching_decr_int_now_zero(&aBlock->flags)) {
|
||||
// Tell GC we no longer have our own refcounts. GC will decr its refcount
|
||||
// and unless someone has done a CFRetain or marked it uncollectable it will
|
||||
// now be subject to GC reclamation.
|
||||
_Block_setHasRefcount(aBlock, false);
|
||||
}
|
||||
}
|
||||
else if (aBlock->flags & BLOCK_NEEDS_FREE) {
|
||||
if (latching_decr_int_should_deallocate(&aBlock->flags)) {
|
||||
_Block_call_dispose_helper(aBlock);
|
||||
_Block_destructInstance(aBlock);
|
||||
_Block_deallocator(aBlock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BLOCK_EXPORT
|
||||
bool _Block_tryRetain(const void *arg) {
|
||||
struct Block_layout *aBlock = (struct Block_layout *)arg;
|
||||
return latching_incr_int_not_deallocating(&aBlock->flags);
|
||||
}
|
||||
|
||||
BLOCK_EXPORT
|
||||
bool _Block_isDeallocating(const void *arg) {
|
||||
struct Block_layout *aBlock = (struct Block_layout *)arg;
|
||||
return (aBlock->flags & BLOCK_DEALLOCATING) != 0;
|
||||
}
|
||||
|
||||
// Old Compiler SPI point to release a copied Block used by the compiler in dispose helpers
|
||||
static void _Block_destroy(const void *arg) {
|
||||
struct Block_layout *aBlock;
|
||||
if (!arg) return;
|
||||
aBlock = (struct Block_layout *)arg;
|
||||
if (aBlock->flags & BLOCK_IS_GC) {
|
||||
// assert(aBlock->Block_flags & BLOCK_HAS_CTOR);
|
||||
return; // ignore, we are being called because of a DTOR
|
||||
}
|
||||
_Block_release(aBlock);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/************************************************************
|
||||
*
|
||||
* SPI used by other layers
|
||||
*
|
||||
***********************************************************/
|
||||
|
||||
// SPI, also internal. Called from NSAutoBlock only under GC
|
||||
BLOCK_EXPORT
|
||||
void *_Block_copy_collectable(const void *aBlock) {
|
||||
return _Block_copy_internal(aBlock, false);
|
||||
}
|
||||
|
||||
|
||||
// SPI
|
||||
BLOCK_EXPORT
|
||||
size_t Block_size(void *aBlock) {
|
||||
return ((struct Block_layout *)aBlock)->descriptor->size;
|
||||
}
|
||||
|
||||
BLOCK_EXPORT
|
||||
bool _Block_use_stret(void *aBlock) {
|
||||
struct Block_layout *layout = (struct Block_layout *)aBlock;
|
||||
|
||||
int requiredFlags = BLOCK_HAS_SIGNATURE | BLOCK_USE_STRET;
|
||||
return (layout->flags & requiredFlags) == requiredFlags;
|
||||
}
|
||||
|
||||
// Checks for a valid signature, not merely the BLOCK_HAS_SIGNATURE bit.
|
||||
BLOCK_EXPORT
|
||||
bool _Block_has_signature(void *aBlock) {
|
||||
return _Block_signature(aBlock) ? true : false;
|
||||
}
|
||||
|
||||
BLOCK_EXPORT
|
||||
const char * _Block_signature(void *aBlock)
|
||||
{
|
||||
struct Block_descriptor_3 *desc3 = _Block_descriptor_3(aBlock);
|
||||
if (!desc3) return NULL;
|
||||
|
||||
return desc3->signature;
|
||||
}
|
||||
|
||||
BLOCK_EXPORT
|
||||
const char * _Block_layout(void *aBlock)
|
||||
{
|
||||
// Don't return extended layout to callers expecting GC layout
|
||||
struct Block_layout *layout = (struct Block_layout *)aBlock;
|
||||
if (layout->flags & BLOCK_HAS_EXTENDED_LAYOUT) return NULL;
|
||||
|
||||
struct Block_descriptor_3 *desc3 = _Block_descriptor_3(aBlock);
|
||||
if (!desc3) return NULL;
|
||||
|
||||
return desc3->layout;
|
||||
}
|
||||
|
||||
BLOCK_EXPORT
|
||||
const char * _Block_extended_layout(void *aBlock)
|
||||
{
|
||||
// Don't return GC layout to callers expecting extended layout
|
||||
struct Block_layout *layout = (struct Block_layout *)aBlock;
|
||||
if (! (layout->flags & BLOCK_HAS_EXTENDED_LAYOUT)) return NULL;
|
||||
|
||||
struct Block_descriptor_3 *desc3 = _Block_descriptor_3(aBlock);
|
||||
if (!desc3) return NULL;
|
||||
|
||||
// Return empty string (all non-object bytes) instead of NULL
|
||||
// so callers can distinguish "empty layout" from "no layout".
|
||||
if (!desc3->layout) return "";
|
||||
else return desc3->layout;
|
||||
}
|
||||
|
||||
#if !defined(_MSC_VER) || defined(__clang__)
|
||||
#pragma mark Compiler SPI entry points
|
||||
#endif
|
||||
|
||||
|
||||
/*******************************************************
|
||||
|
||||
Entry points used by the compiler - the real API!
|
||||
|
||||
|
||||
A Block can reference four different kinds of things that require help when the Block is copied to the heap.
|
||||
1) C++ stack based objects
|
||||
2) References to Objective-C objects
|
||||
3) Other Blocks
|
||||
4) __block variables
|
||||
|
||||
In these cases helper functions are synthesized by the compiler for use in Block_copy and Block_release, called the copy and dispose helpers. The copy helper emits a call to the C++ const copy constructor for C++ stack based objects and for the rest calls into the runtime support function _Block_object_assign. The dispose helper has a call to the C++ destructor for case 1 and a call into _Block_object_dispose for the rest.
|
||||
|
||||
The flags parameter of _Block_object_assign and _Block_object_dispose is set to
|
||||
* BLOCK_FIELD_IS_OBJECT (3), for the case of an Objective-C Object,
|
||||
* BLOCK_FIELD_IS_BLOCK (7), for the case of another Block, and
|
||||
* BLOCK_FIELD_IS_BYREF (8), for the case of a __block variable.
|
||||
If the __block variable is marked weak the compiler also or's in BLOCK_FIELD_IS_WEAK (16)
|
||||
|
||||
So the Block copy/dispose helpers should only ever generate the four flag values of 3, 7, 8, and 24.
|
||||
|
||||
When a __block variable is either a C++ object, an Objective-C object, or another Block then the compiler also generates copy/dispose helper functions. Similarly to the Block copy helper, the "__block" copy helper (formerly and still a.k.a. "byref" copy helper) will do a C++ copy constructor (not a const one though!) and the dispose helper will do the destructor. And similarly the helpers will call into the same two support functions with the same values for objects and Blocks with the additional BLOCK_BYREF_CALLER (128) bit of information supplied.
|
||||
|
||||
So the __block copy/dispose helpers will generate flag values of 3 or 7 for objects and Blocks respectively, with BLOCK_FIELD_IS_WEAK (16) or'ed as appropriate and always 128 or'd in, for the following set of possibilities:
|
||||
__block id 128+3 (0x83)
|
||||
__block (^Block) 128+7 (0x87)
|
||||
__weak __block id 128+3+16 (0x93)
|
||||
__weak __block (^Block) 128+7+16 (0x97)
|
||||
|
||||
|
||||
********************************************************/
|
||||
|
||||
//
|
||||
// When Blocks or Block_byrefs hold objects then their copy routine helpers use this entry point
|
||||
// to do the assignment.
|
||||
//
|
||||
BLOCK_EXPORT
|
||||
void _Block_object_assign(void *destAddr, const void *object, const int flags) {
|
||||
switch (os_assumes(flags & BLOCK_ALL_COPY_DISPOSE_FLAGS)) {
|
||||
case BLOCK_FIELD_IS_OBJECT:
|
||||
/*******
|
||||
id object = ...;
|
||||
[^{ object; } copy];
|
||||
********/
|
||||
|
||||
_Block_retain_object(object);
|
||||
_Block_assign((void *)object, destAddr);
|
||||
break;
|
||||
|
||||
case BLOCK_FIELD_IS_BLOCK:
|
||||
/*******
|
||||
void (^object)(void) = ...;
|
||||
[^{ object; } copy];
|
||||
********/
|
||||
|
||||
_Block_assign(_Block_copy_internal(object, false), destAddr);
|
||||
break;
|
||||
|
||||
case BLOCK_FIELD_IS_BYREF | BLOCK_FIELD_IS_WEAK:
|
||||
case BLOCK_FIELD_IS_BYREF:
|
||||
/*******
|
||||
// copy the onstack __block container to the heap
|
||||
__block ... x;
|
||||
__weak __block ... x;
|
||||
[^{ x; } copy];
|
||||
********/
|
||||
|
||||
_Block_byref_assign_copy(destAddr, object, flags);
|
||||
break;
|
||||
|
||||
case BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT:
|
||||
case BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK:
|
||||
/*******
|
||||
// copy the actual field held in the __block container
|
||||
__block id object;
|
||||
__block void (^object)(void);
|
||||
[^{ object; } copy];
|
||||
********/
|
||||
|
||||
// under manual retain release __block object/block variables are dangling
|
||||
_Block_assign((void *)object, destAddr);
|
||||
break;
|
||||
|
||||
case BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT | BLOCK_FIELD_IS_WEAK:
|
||||
case BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK | BLOCK_FIELD_IS_WEAK:
|
||||
/*******
|
||||
// copy the actual field held in the __block container
|
||||
__weak __block id object;
|
||||
__weak __block void (^object)(void);
|
||||
[^{ object; } copy];
|
||||
********/
|
||||
|
||||
_Block_assign_weak(object, destAddr);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// When Blocks or Block_byrefs hold objects their destroy helper routines call this entry point
|
||||
// to help dispose of the contents
|
||||
// Used initially only for __attribute__((NSObject)) marked pointers.
|
||||
BLOCK_EXPORT
|
||||
void _Block_object_dispose(const void *object, const int flags) {
|
||||
switch (os_assumes(flags & BLOCK_ALL_COPY_DISPOSE_FLAGS)) {
|
||||
case BLOCK_FIELD_IS_BYREF | BLOCK_FIELD_IS_WEAK:
|
||||
case BLOCK_FIELD_IS_BYREF:
|
||||
// get rid of the __block data structure held in a Block
|
||||
_Block_byref_release(object);
|
||||
break;
|
||||
case BLOCK_FIELD_IS_BLOCK:
|
||||
_Block_destroy(object);
|
||||
break;
|
||||
case BLOCK_FIELD_IS_OBJECT:
|
||||
_Block_release_object(object);
|
||||
break;
|
||||
case BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT:
|
||||
case BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK:
|
||||
case BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_OBJECT | BLOCK_FIELD_IS_WEAK:
|
||||
case BLOCK_BYREF_CALLER | BLOCK_FIELD_IS_BLOCK | BLOCK_FIELD_IS_WEAK:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
194
Telegram/ThirdParty/dispatch/src/CMakeLists.txt
vendored
Normal file
194
Telegram/ThirdParty/dispatch/src/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,194 @@
|
||||
|
||||
if(NOT CMAKE_SYSTEM_NAME STREQUAL Darwin)
|
||||
add_subdirectory(BlocksRuntime)
|
||||
endif()
|
||||
|
||||
add_library(dispatch
|
||||
allocator.c
|
||||
apply.c
|
||||
benchmark.c
|
||||
data.c
|
||||
init.c
|
||||
introspection.c
|
||||
io.c
|
||||
mach.c
|
||||
object.c
|
||||
once.c
|
||||
queue.c
|
||||
semaphore.c
|
||||
source.c
|
||||
time.c
|
||||
transform.c
|
||||
voucher.c
|
||||
shims.c
|
||||
protocol.defs
|
||||
provider.d
|
||||
allocator_internal.h
|
||||
data_internal.h
|
||||
inline_internal.h
|
||||
internal.h
|
||||
introspection_internal.h
|
||||
io_internal.h
|
||||
mach_internal.h
|
||||
object_internal.h
|
||||
queue_internal.h
|
||||
semaphore_internal.h
|
||||
shims.h
|
||||
source_internal.h
|
||||
trace.h
|
||||
voucher_internal.h
|
||||
event/event.c
|
||||
event/event_config.h
|
||||
event/event_epoll.c
|
||||
event/event_internal.h
|
||||
event/event_kevent.c
|
||||
event/event_windows.c
|
||||
firehose/firehose_internal.h
|
||||
shims/android_stubs.h
|
||||
shims/atomic.h
|
||||
shims/atomic_sfb.h
|
||||
shims/getprogname.h
|
||||
shims/hw_config.h
|
||||
shims/lock.c
|
||||
shims/lock.h
|
||||
shims/perfmon.h
|
||||
shims/time.h
|
||||
shims/tsd.h
|
||||
shims/yield.c
|
||||
shims/yield.h)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL Windows)
|
||||
target_sources(dispatch PRIVATE
|
||||
shims/generic_sys_queue.h
|
||||
shims/generic_win_stubs.c
|
||||
shims/generic_win_stubs.h
|
||||
shims/getprogname.c)
|
||||
endif()
|
||||
|
||||
if(DISPATCH_USE_INTERNAL_WORKQUEUE)
|
||||
target_sources(dispatch PRIVATE
|
||||
event/workqueue.c
|
||||
event/workqueue_internal.h)
|
||||
endif()
|
||||
|
||||
target_sources(dispatch PRIVATE
|
||||
block.cpp)
|
||||
|
||||
if(ENABLE_DTRACE)
|
||||
dtrace_usdt_probe(${CMAKE_CURRENT_SOURCE_DIR}/provider.d OUTPUT_SOURCES
|
||||
dispatch_dtrace_provider_headers)
|
||||
target_sources(dispatch PRIVATE
|
||||
${dispatch_dtrace_provider_headers})
|
||||
endif()
|
||||
|
||||
if(HAVE_OBJC)
|
||||
# TODO(compnerd) split DispatchStubs.cc into a separate component for the ObjC
|
||||
# registration and a separate component for the swift compiler's emission of a
|
||||
# call to the ObjC autorelease elision entry point.
|
||||
target_sources(dispatch PRIVATE
|
||||
data.m
|
||||
object.m
|
||||
swift/DispatchStubs.cc)
|
||||
endif()
|
||||
|
||||
|
||||
set_target_properties(dispatch PROPERTIES
|
||||
POSITION_INDEPENDENT_CODE YES)
|
||||
|
||||
target_include_directories(dispatch PUBLIC
|
||||
${PROJECT_BINARY_DIR}
|
||||
${PROJECT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR})
|
||||
target_include_directories(dispatch PRIVATE
|
||||
${PROJECT_SOURCE_DIR}/private)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL Windows)
|
||||
target_compile_definitions(dispatch PRIVATE
|
||||
_CRT_NONSTDC_NO_WARNINGS
|
||||
_CRT_SECURE_NO_WARNINGS)
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL Android)
|
||||
target_compile_options(dispatch PRIVATE
|
||||
-U_GNU_SOURCE)
|
||||
endif()
|
||||
if(DISPATCH_ENABLE_ASSERTS)
|
||||
target_compile_definitions(dispatch PRIVATE
|
||||
DISPATCH_DEBUG=1)
|
||||
endif()
|
||||
|
||||
if("${CMAKE_C_SIMULATE_ID}" STREQUAL "MSVC")
|
||||
target_compile_options(dispatch PRIVATE /EHs-c-)
|
||||
target_compile_options(dispatch PRIVATE /W3)
|
||||
else()
|
||||
target_compile_options(dispatch PRIVATE -fno-exceptions)
|
||||
target_compile_options(dispatch PRIVATE -Wall)
|
||||
endif()
|
||||
|
||||
# Work around a release-mode miscompile on windows arm64
|
||||
# Disable /Os and /Ot in /O1 and /O2 on queue.c
|
||||
if(("${CMAKE_C_SIMULATE_ID}" STREQUAL "MSVC") AND
|
||||
(("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "ARM64") OR
|
||||
("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "aarch64")))
|
||||
string(TOUPPER "${CMAKE_BUILD_TYPE}" uppercase_CMAKE_BUILD_TYPE)
|
||||
set(FLAGS_BUILD_TYPE "${CMAKE_C_FLAGS_${uppercase_CMAKE_BUILD_TYPE}}")
|
||||
string(REGEX MATCHALL "/[Oo][12]" FLAGS "${CMAKE_C_FLAGS} ${FLAGS_BUILD_TYPE}")
|
||||
if (FLAGS)
|
||||
if (FLAGS MATCHES "1$")
|
||||
set(FLAGS "/Od;/Og;/Oy;/Ob2;/GF;/Gy")
|
||||
elseif (FLAGS MATCHES "2$")
|
||||
set(FLAGS "/Od;/Og;/Oi;/Oy;/Ob2;/GF;/Gy")
|
||||
endif()
|
||||
set_source_files_properties(queue.c PROPERTIES COMPILE_OPTIONS "${FLAGS}")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# FIXME(compnerd) add check for -fblocks?
|
||||
target_compile_options(dispatch PRIVATE -fblocks)
|
||||
|
||||
check_c_compiler_flag("-momit-leaf-frame-pointer -Werror -Wall -O3" C_SUPPORTS_OMIT_LEAF_FRAME_POINTER)
|
||||
if (C_SUPPORTS_OMIT_LEAF_FRAME_POINTER)
|
||||
target_compile_options(dispatch PRIVATE -momit-leaf-frame-pointer)
|
||||
endif()
|
||||
|
||||
if(LibRT_FOUND)
|
||||
target_link_libraries(dispatch PRIVATE RT::rt)
|
||||
endif()
|
||||
target_link_libraries(dispatch PRIVATE
|
||||
Threads::Threads)
|
||||
target_link_libraries(dispatch PUBLIC
|
||||
BlocksRuntime::BlocksRuntime)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL Windows)
|
||||
target_link_libraries(dispatch PRIVATE
|
||||
AdvAPI32
|
||||
ShLwApi
|
||||
WS2_32
|
||||
WinMM
|
||||
synchronization)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
|
||||
set_property(TARGET dispatch APPEND_STRING PROPERTY LINK_FLAGS
|
||||
"-Xlinker -compatibility_version -Xlinker 1"
|
||||
"-Xlinker -current_version -Xlinker ${VERSION}"
|
||||
"-Xlinker -dead_strip"
|
||||
"-Xlinker -alias_list -Xlinker ${PROJECT_SOURCE_DIR}/xcodeconfig/libdispatch.aliases")
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_SYSTEM_NAME MATCHES "Darwin|Windows")
|
||||
set_target_properties(dispatch PROPERTIES INSTALL_RPATH "$ORIGIN")
|
||||
endif()
|
||||
|
||||
if(LINKER_SUPPORTS_BUILD_ID)
|
||||
target_link_options(dispatch PRIVATE "LINKER:--build-id=sha1")
|
||||
endif()
|
||||
|
||||
if(ENABLE_SWIFT)
|
||||
add_subdirectory(swift)
|
||||
endif()
|
||||
|
||||
set_property(GLOBAL APPEND PROPERTY DISPATCH_EXPORTS dispatch)
|
||||
install(TARGETS dispatch
|
||||
EXPORT dispatchExports
|
||||
ARCHIVE DESTINATION ${INSTALL_TARGET_DIR}
|
||||
LIBRARY DESTINATION ${INSTALL_TARGET_DIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
|
||||
797
Telegram/ThirdParty/dispatch/src/allocator.c
vendored
Normal file
797
Telegram/ThirdParty/dispatch/src/allocator.c
vendored
Normal file
@@ -0,0 +1,797 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2013 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#include "internal.h"
|
||||
#include "allocator_internal.h"
|
||||
|
||||
#if DISPATCH_ALLOCATOR
|
||||
|
||||
#ifndef VM_MEMORY_LIBDISPATCH
|
||||
#define VM_MEMORY_LIBDISPATCH 74
|
||||
#endif
|
||||
|
||||
// _dispatch_main_heap is is the first heap in the linked list, where searches
|
||||
// always begin.
|
||||
//
|
||||
// _dispatch_main_heap, and dh_next, are read normally but only written (in
|
||||
// try_create_heap) by cmpxchg. They start life at 0, and are only written
|
||||
// once to non-zero. They are not marked volatile. There is a small risk that
|
||||
// some thread may see a stale 0 value and enter try_create_heap. It will
|
||||
// waste some time in an allocate syscall, but eventually it will try to
|
||||
// cmpxchg, expecting to overwrite 0 with an address. This will fail
|
||||
// (because another thread already did this), the thread will deallocate the
|
||||
// unused allocated memory, and continue with the new value.
|
||||
//
|
||||
// If something goes wrong here, the symptom would be a NULL dereference
|
||||
// in alloc_continuation_from_heap or _magazine when derefing the magazine ptr.
|
||||
DISPATCH_GLOBAL(dispatch_heap_t _dispatch_main_heap);
|
||||
|
||||
DISPATCH_ALWAYS_INLINE
|
||||
static void
|
||||
set_last_found_page(bitmap_t *val)
|
||||
{
|
||||
dispatch_assert(_dispatch_main_heap);
|
||||
unsigned int cpu = _dispatch_cpu_number();
|
||||
_dispatch_main_heap[cpu].header.last_found_page = val;
|
||||
}
|
||||
|
||||
DISPATCH_ALWAYS_INLINE
|
||||
static bitmap_t *
|
||||
last_found_page(void)
|
||||
{
|
||||
dispatch_assert(_dispatch_main_heap);
|
||||
unsigned int cpu = _dispatch_cpu_number();
|
||||
return _dispatch_main_heap[cpu].header.last_found_page;
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark dispatch_alloc_bitmaps
|
||||
|
||||
DISPATCH_ALWAYS_INLINE_NDEBUG DISPATCH_CONST
|
||||
static bitmap_t *
|
||||
supermap_address(struct dispatch_magazine_s *magazine, unsigned int supermap)
|
||||
{
|
||||
return &magazine->supermaps[supermap];
|
||||
}
|
||||
|
||||
DISPATCH_ALWAYS_INLINE_NDEBUG DISPATCH_CONST
|
||||
static bitmap_t *
|
||||
bitmap_address(struct dispatch_magazine_s *magazine, unsigned int supermap,
|
||||
unsigned int map)
|
||||
{
|
||||
return &magazine->maps[supermap][map];
|
||||
}
|
||||
|
||||
DISPATCH_ALWAYS_INLINE_NDEBUG DISPATCH_CONST
|
||||
static dispatch_continuation_t
|
||||
continuation_address(struct dispatch_magazine_s *magazine,
|
||||
unsigned int supermap, unsigned int map, unsigned int index)
|
||||
{
|
||||
#if DISPATCH_DEBUG
|
||||
dispatch_assert(supermap < SUPERMAPS_PER_MAGAZINE);
|
||||
dispatch_assert(map < BITMAPS_PER_SUPERMAP);
|
||||
dispatch_assert(index < CONTINUATIONS_PER_BITMAP);
|
||||
#endif
|
||||
return (dispatch_continuation_t)&magazine->conts[supermap][map][index];
|
||||
}
|
||||
|
||||
DISPATCH_ALWAYS_INLINE_NDEBUG DISPATCH_CONST
|
||||
static struct dispatch_magazine_s *
|
||||
magazine_for_continuation(dispatch_continuation_t c)
|
||||
{
|
||||
return (struct dispatch_magazine_s *)((uintptr_t)c & MAGAZINE_MASK);
|
||||
}
|
||||
|
||||
DISPATCH_ALWAYS_INLINE_NDEBUG
|
||||
static void
|
||||
get_cont_and_indices_for_bitmap_and_index(bitmap_t *bitmap,
|
||||
unsigned int index, dispatch_continuation_t *continuation_out,
|
||||
bitmap_t **supermap_out, unsigned int *bitmap_index_out)
|
||||
{
|
||||
// m_for_c wants a continuation not a bitmap, but it works because it
|
||||
// just masks off the bottom bits of the address.
|
||||
struct dispatch_magazine_s *m = magazine_for_continuation((void *)bitmap);
|
||||
unsigned int mindex = (unsigned int)(bitmap - m->maps[0]);
|
||||
unsigned int bindex = mindex % BITMAPS_PER_SUPERMAP;
|
||||
unsigned int sindex = mindex / BITMAPS_PER_SUPERMAP;
|
||||
dispatch_assert(&m->maps[sindex][bindex] == bitmap);
|
||||
if (likely(continuation_out)) {
|
||||
*continuation_out = continuation_address(m, sindex, bindex, index);
|
||||
}
|
||||
if (likely(supermap_out)) *supermap_out = supermap_address(m, sindex);
|
||||
if (likely(bitmap_index_out)) *bitmap_index_out = bindex;
|
||||
}
|
||||
|
||||
DISPATCH_ALWAYS_INLINE_NDEBUG DISPATCH_CONST
|
||||
static bool
|
||||
continuation_is_in_first_page(dispatch_continuation_t c)
|
||||
{
|
||||
#if PACK_FIRST_PAGE_WITH_CONTINUATIONS
|
||||
// (the base of c's magazine == the base of c's page)
|
||||
// => c is in first page of magazine
|
||||
return (((uintptr_t)c & MAGAZINE_MASK) ==
|
||||
((uintptr_t)c & ~(uintptr_t)DISPATCH_ALLOCATOR_PAGE_MASK));
|
||||
#else
|
||||
(void)c;
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
DISPATCH_ALWAYS_INLINE_NDEBUG
|
||||
static void
|
||||
get_maps_and_indices_for_continuation(dispatch_continuation_t c,
|
||||
bitmap_t **supermap_out, unsigned int *bitmap_index_out,
|
||||
bitmap_t **bitmap_out, unsigned int *index_out)
|
||||
{
|
||||
unsigned int cindex, sindex, index, mindex;
|
||||
padded_continuation *p = (padded_continuation *)c;
|
||||
struct dispatch_magazine_s *m = magazine_for_continuation(c);
|
||||
#if PACK_FIRST_PAGE_WITH_CONTINUATIONS
|
||||
if (likely(continuation_is_in_first_page(c))) {
|
||||
cindex = (unsigned int)(p - m->fp_conts);
|
||||
index = cindex % CONTINUATIONS_PER_BITMAP;
|
||||
mindex = cindex / CONTINUATIONS_PER_BITMAP;
|
||||
if (likely(supermap_out)) *supermap_out = NULL;
|
||||
if (likely(bitmap_index_out)) *bitmap_index_out = mindex;
|
||||
if (likely(bitmap_out)) *bitmap_out = &m->fp_maps[mindex];
|
||||
if (likely(index_out)) *index_out = index;
|
||||
return;
|
||||
}
|
||||
#endif // PACK_FIRST_PAGE_WITH_CONTINUATIONS
|
||||
cindex = (unsigned int)(p - (padded_continuation *)m->conts);
|
||||
sindex = cindex / (BITMAPS_PER_SUPERMAP * CONTINUATIONS_PER_BITMAP);
|
||||
mindex = (cindex / CONTINUATIONS_PER_BITMAP) % BITMAPS_PER_SUPERMAP;
|
||||
index = cindex % CONTINUATIONS_PER_BITMAP;
|
||||
if (likely(supermap_out)) *supermap_out = &m->supermaps[sindex];
|
||||
if (likely(bitmap_index_out)) *bitmap_index_out = mindex;
|
||||
if (likely(bitmap_out)) *bitmap_out = &m->maps[sindex][mindex];
|
||||
if (likely(index_out)) *index_out = index;
|
||||
}
|
||||
|
||||
// Base address of page, or NULL if this page shouldn't be madvise()d
|
||||
DISPATCH_ALWAYS_INLINE_NDEBUG DISPATCH_CONST
|
||||
static void *
|
||||
madvisable_page_base_for_continuation(dispatch_continuation_t c)
|
||||
{
|
||||
if (likely(continuation_is_in_first_page(c))) {
|
||||
return NULL;
|
||||
}
|
||||
void *page_base = (void *)((uintptr_t)c &
|
||||
~(uintptr_t)DISPATCH_ALLOCATOR_PAGE_MASK);
|
||||
#if DISPATCH_DEBUG
|
||||
struct dispatch_magazine_s *m = magazine_for_continuation(c);
|
||||
if (unlikely(page_base < (void *)&m->conts)) {
|
||||
DISPATCH_INTERNAL_CRASH(page_base, "madvisable continuation too low");
|
||||
}
|
||||
if (unlikely(page_base > (void *)&m->conts[SUPERMAPS_PER_MAGAZINE-1]
|
||||
[BITMAPS_PER_SUPERMAP-1][CONTINUATIONS_PER_BITMAP-1])) {
|
||||
DISPATCH_INTERNAL_CRASH(page_base, "madvisable continuation too high");
|
||||
}
|
||||
#endif
|
||||
return page_base;
|
||||
}
|
||||
|
||||
// Bitmap that controls the first few continuations in the same page as
|
||||
// the continuations controlled by the passed bitmap. Undefined results if the
|
||||
// passed bitmap controls continuations in the first page.
|
||||
DISPATCH_ALWAYS_INLINE_NDEBUG DISPATCH_CONST
|
||||
static bitmap_t *
|
||||
first_bitmap_in_same_page(bitmap_t *b)
|
||||
{
|
||||
#if DISPATCH_DEBUG
|
||||
struct dispatch_magazine_s *m;
|
||||
m = magazine_for_continuation((void*)b);
|
||||
dispatch_assert(b >= &m->maps[0][0]);
|
||||
dispatch_assert(b < &m->maps[SUPERMAPS_PER_MAGAZINE]
|
||||
[BITMAPS_PER_SUPERMAP]);
|
||||
#endif
|
||||
const uintptr_t PAGE_BITMAP_MASK = (BITMAPS_PER_PAGE *
|
||||
BYTES_PER_BITMAP) - 1;
|
||||
return (bitmap_t *)((uintptr_t)b & ~PAGE_BITMAP_MASK);
|
||||
}
|
||||
|
||||
DISPATCH_ALWAYS_INLINE_NDEBUG DISPATCH_CONST
|
||||
static bool
|
||||
bitmap_is_full(bitmap_t bits)
|
||||
{
|
||||
return (bits == BITMAP_ALL_ONES);
|
||||
}
|
||||
|
||||
#define NO_BITS_WERE_UNSET (UINT_MAX)
|
||||
|
||||
// max_index is the 0-based position of the most significant bit that is
|
||||
// allowed to be set.
|
||||
DISPATCH_ALWAYS_INLINE_NDEBUG
|
||||
static unsigned int
|
||||
bitmap_set_first_unset_bit_upto_index(volatile bitmap_t *bitmap,
|
||||
unsigned int max_index)
|
||||
{
|
||||
// No barriers needed in acquire path: the just-allocated
|
||||
// continuation is "uninitialized", so the caller shouldn't
|
||||
// load from it before storing, so we don't need to guard
|
||||
// against reordering those loads.
|
||||
dispatch_assert(sizeof(*bitmap) == sizeof(unsigned long));
|
||||
return os_atomic_set_first_bit(bitmap, max_index);
|
||||
}
|
||||
|
||||
DISPATCH_ALWAYS_INLINE
|
||||
static unsigned int
|
||||
bitmap_set_first_unset_bit(volatile bitmap_t *bitmap)
|
||||
{
|
||||
return bitmap_set_first_unset_bit_upto_index(bitmap, UINT_MAX);
|
||||
}
|
||||
|
||||
#define CLEAR_EXCLUSIVELY true
|
||||
#define CLEAR_NONEXCLUSIVELY false
|
||||
|
||||
// Return true if this bit was the last in the bitmap, and it is now all zeroes
|
||||
DISPATCH_ALWAYS_INLINE_NDEBUG
|
||||
static bool
|
||||
bitmap_clear_bit(volatile bitmap_t *bitmap, unsigned int index,
|
||||
bool exclusively)
|
||||
{
|
||||
#if DISPATCH_DEBUG
|
||||
dispatch_assert(index < CONTINUATIONS_PER_BITMAP);
|
||||
#endif
|
||||
const bitmap_t mask = BITMAP_C(1) << index;
|
||||
bitmap_t b;
|
||||
|
||||
if (exclusively == CLEAR_EXCLUSIVELY) {
|
||||
if (unlikely((*bitmap & mask) == 0)) {
|
||||
DISPATCH_CLIENT_CRASH(*bitmap,
|
||||
"Corruption: failed to clear bit exclusively");
|
||||
}
|
||||
}
|
||||
|
||||
// and-and-fetch
|
||||
b = os_atomic_and(bitmap, ~mask, release);
|
||||
return b == 0;
|
||||
}
|
||||
|
||||
DISPATCH_ALWAYS_INLINE_NDEBUG
|
||||
static void
|
||||
mark_bitmap_as_full_if_still_full(volatile bitmap_t *supermap,
|
||||
unsigned int bitmap_index, volatile bitmap_t *bitmap)
|
||||
{
|
||||
#if DISPATCH_DEBUG
|
||||
dispatch_assert(bitmap_index < BITMAPS_PER_SUPERMAP);
|
||||
#endif
|
||||
const bitmap_t mask = BITMAP_C(1) << bitmap_index;
|
||||
bitmap_t s, s_new;
|
||||
|
||||
// No barriers because supermaps are only advisory, they
|
||||
// don't protect access to other memory.
|
||||
os_atomic_rmw_loop(supermap, s, s_new, relaxed, {
|
||||
if (!bitmap_is_full(*bitmap)) {
|
||||
os_atomic_rmw_loop_give_up(return);
|
||||
}
|
||||
s_new = s | mask;
|
||||
});
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark dispatch_alloc_continuation_alloc
|
||||
|
||||
#if PACK_FIRST_PAGE_WITH_CONTINUATIONS
|
||||
DISPATCH_ALWAYS_INLINE_NDEBUG
|
||||
static dispatch_continuation_t
|
||||
alloc_continuation_from_first_page(struct dispatch_magazine_s *magazine)
|
||||
{
|
||||
unsigned int i, index, continuation_index;
|
||||
|
||||
// TODO: unroll if this is hot?
|
||||
for (i = 0; i < FULL_BITMAPS_IN_FIRST_PAGE; i++) {
|
||||
index = bitmap_set_first_unset_bit(&magazine->fp_maps[i]);
|
||||
if (likely(index != NO_BITS_WERE_UNSET)) goto found;
|
||||
}
|
||||
if (REMAINDERED_CONTINUATIONS_IN_FIRST_PAGE) {
|
||||
index = bitmap_set_first_unset_bit_upto_index(&magazine->fp_maps[i],
|
||||
REMAINDERED_CONTINUATIONS_IN_FIRST_PAGE - 1);
|
||||
if (likely(index != NO_BITS_WERE_UNSET)) goto found;
|
||||
}
|
||||
return NULL;
|
||||
|
||||
found:
|
||||
continuation_index = (i * CONTINUATIONS_PER_BITMAP) + index;
|
||||
return (dispatch_continuation_t)&magazine->fp_conts[continuation_index];
|
||||
}
|
||||
#endif // PACK_FIRST_PAGE_WITH_CONTINUATIONS
|
||||
|
||||
DISPATCH_ALWAYS_INLINE_NDEBUG
|
||||
static dispatch_continuation_t
|
||||
alloc_continuation_from_magazine(struct dispatch_magazine_s *magazine)
|
||||
{
|
||||
unsigned int s, b, index;
|
||||
|
||||
for (s = 0; s < SUPERMAPS_PER_MAGAZINE; s++) {
|
||||
volatile bitmap_t *supermap = supermap_address(magazine, s);
|
||||
if (bitmap_is_full(*supermap)) {
|
||||
continue;
|
||||
}
|
||||
for (b = 0; b < BITMAPS_PER_SUPERMAP; b++) {
|
||||
volatile bitmap_t *bitmap = bitmap_address(magazine, s, b);
|
||||
index = bitmap_set_first_unset_bit(bitmap);
|
||||
if (index != NO_BITS_WERE_UNSET) {
|
||||
set_last_found_page(
|
||||
first_bitmap_in_same_page((bitmap_t *)bitmap));
|
||||
mark_bitmap_as_full_if_still_full(supermap, b, bitmap);
|
||||
return continuation_address(magazine, s, b, index);
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DISPATCH_NOINLINE
|
||||
static void
|
||||
_dispatch_alloc_try_create_heap(dispatch_heap_t *heap_ptr)
|
||||
{
|
||||
#if HAVE_MACH
|
||||
kern_return_t kr;
|
||||
mach_vm_size_t vm_size = MAGAZINES_PER_HEAP * BYTES_PER_MAGAZINE;
|
||||
mach_vm_offset_t vm_mask = ~MAGAZINE_MASK;
|
||||
mach_vm_address_t vm_addr = vm_page_size;
|
||||
while (unlikely(kr = mach_vm_map(mach_task_self(), &vm_addr, vm_size,
|
||||
vm_mask, VM_FLAGS_ANYWHERE | VM_MAKE_TAG(VM_MEMORY_LIBDISPATCH),
|
||||
MEMORY_OBJECT_NULL, 0, FALSE, VM_PROT_DEFAULT, VM_PROT_ALL,
|
||||
VM_INHERIT_DEFAULT))) {
|
||||
if (kr != KERN_NO_SPACE) {
|
||||
DISPATCH_CLIENT_CRASH(kr, "Could not allocate heap");
|
||||
}
|
||||
_dispatch_temporary_resource_shortage();
|
||||
vm_addr = vm_page_size;
|
||||
}
|
||||
uintptr_t aligned_region = (uintptr_t)vm_addr;
|
||||
#else // HAVE_MACH
|
||||
const size_t region_sz = (1 + MAGAZINES_PER_HEAP) * BYTES_PER_MAGAZINE;
|
||||
void *region_p;
|
||||
while (!dispatch_assume((region_p = mmap(NULL, region_sz,
|
||||
PROT_READ|PROT_WRITE, MAP_ANON | MAP_PRIVATE,
|
||||
VM_MAKE_TAG(VM_MEMORY_LIBDISPATCH), 0)) != MAP_FAILED)) {
|
||||
_dispatch_temporary_resource_shortage();
|
||||
}
|
||||
uintptr_t region = (uintptr_t)region_p;
|
||||
uintptr_t region_end = region + region_sz;
|
||||
uintptr_t aligned_region, aligned_region_end;
|
||||
uintptr_t bottom_slop_len, top_slop_len;
|
||||
// Realign if needed; find the slop at top/bottom to unmap
|
||||
if ((region & ~(MAGAZINE_MASK)) == 0) {
|
||||
bottom_slop_len = 0;
|
||||
aligned_region = region;
|
||||
aligned_region_end = region_end - BYTES_PER_MAGAZINE;
|
||||
top_slop_len = BYTES_PER_MAGAZINE;
|
||||
} else {
|
||||
aligned_region = (region & MAGAZINE_MASK) + BYTES_PER_MAGAZINE;
|
||||
aligned_region_end = aligned_region +
|
||||
(MAGAZINES_PER_HEAP * BYTES_PER_MAGAZINE);
|
||||
bottom_slop_len = aligned_region - region;
|
||||
top_slop_len = BYTES_PER_MAGAZINE - bottom_slop_len;
|
||||
}
|
||||
#if DISPATCH_DEBUG
|
||||
// Double-check our math.
|
||||
dispatch_assert(aligned_region % DISPATCH_ALLOCATOR_PAGE_SIZE == 0);
|
||||
dispatch_assert(aligned_region % vm_kernel_page_size == 0);
|
||||
dispatch_assert(aligned_region_end % DISPATCH_ALLOCATOR_PAGE_SIZE == 0);
|
||||
dispatch_assert(aligned_region_end % vm_kernel_page_size == 0);
|
||||
dispatch_assert(aligned_region_end > aligned_region);
|
||||
dispatch_assert(top_slop_len % DISPATCH_ALLOCATOR_PAGE_SIZE == 0);
|
||||
dispatch_assert(bottom_slop_len % DISPATCH_ALLOCATOR_PAGE_SIZE == 0);
|
||||
dispatch_assert(aligned_region_end + top_slop_len == region_end);
|
||||
dispatch_assert(region + bottom_slop_len == aligned_region);
|
||||
dispatch_assert(region_sz == bottom_slop_len + top_slop_len +
|
||||
MAGAZINES_PER_HEAP * BYTES_PER_MAGAZINE);
|
||||
if (bottom_slop_len) {
|
||||
(void)dispatch_assume_zero(mprotect((void *)region, bottom_slop_len,
|
||||
PROT_NONE));
|
||||
}
|
||||
if (top_slop_len) {
|
||||
(void)dispatch_assume_zero(mprotect((void *)aligned_region_end,
|
||||
top_slop_len, PROT_NONE));
|
||||
}
|
||||
#else
|
||||
if (bottom_slop_len) {
|
||||
(void)dispatch_assume_zero(munmap((void *)region, bottom_slop_len));
|
||||
}
|
||||
if (top_slop_len) {
|
||||
(void)dispatch_assume_zero(munmap((void *)aligned_region_end,
|
||||
top_slop_len));
|
||||
}
|
||||
#endif // DISPATCH_DEBUG
|
||||
#endif // HAVE_MACH
|
||||
|
||||
if (!os_atomic_cmpxchg(heap_ptr, NULL, (void *)aligned_region,
|
||||
relaxed)) {
|
||||
// If we lost the race to link in the new region, unmap the whole thing.
|
||||
#if DISPATCH_DEBUG
|
||||
(void)dispatch_assume_zero(mprotect((void *)aligned_region,
|
||||
MAGAZINES_PER_HEAP * BYTES_PER_MAGAZINE, PROT_NONE));
|
||||
#else
|
||||
(void)dispatch_assume_zero(munmap((void *)aligned_region,
|
||||
MAGAZINES_PER_HEAP * BYTES_PER_MAGAZINE));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
DISPATCH_NOINLINE
|
||||
static dispatch_continuation_t
|
||||
_dispatch_alloc_continuation_from_heap(dispatch_heap_t heap)
|
||||
{
|
||||
dispatch_continuation_t cont;
|
||||
|
||||
unsigned int cpu_number = _dispatch_cpu_number();
|
||||
#ifdef DISPATCH_DEBUG
|
||||
dispatch_assert(cpu_number < NUM_CPU);
|
||||
#endif
|
||||
|
||||
#if PACK_FIRST_PAGE_WITH_CONTINUATIONS
|
||||
// First try the continuations in the first page for this CPU
|
||||
cont = alloc_continuation_from_first_page(&(heap[cpu_number]));
|
||||
if (likely(cont)) {
|
||||
return cont;
|
||||
}
|
||||
#endif
|
||||
// Next, try the rest of the magazine for this CPU
|
||||
cont = alloc_continuation_from_magazine(&(heap[cpu_number]));
|
||||
return cont;
|
||||
}
|
||||
|
||||
DISPATCH_NOINLINE
|
||||
static dispatch_continuation_t
|
||||
_dispatch_alloc_continuation_from_heap_slow(void)
|
||||
{
|
||||
dispatch_heap_t *heap = &_dispatch_main_heap;
|
||||
dispatch_continuation_t cont;
|
||||
|
||||
for (;;) {
|
||||
if (unlikely(!*heap)) {
|
||||
_dispatch_alloc_try_create_heap(heap);
|
||||
}
|
||||
cont = _dispatch_alloc_continuation_from_heap(*heap);
|
||||
if (likely(cont)) {
|
||||
return cont;
|
||||
}
|
||||
// If we have tuned our parameters right, 99.999% of apps should
|
||||
// never reach this point! The ones that do have gone off the rails...
|
||||
//
|
||||
// Magazine is full? Onto the next heap!
|
||||
// We tried 'stealing' from other CPUs' magazines. The net effect
|
||||
// was worse performance from more wasted search time and more
|
||||
// cache contention.
|
||||
|
||||
// rdar://11378331
|
||||
// Future optimization: start at the page we last used, start
|
||||
// in the *zone* we last used. But this would only improve deeply
|
||||
// pathological cases like dispatch_starfish
|
||||
heap = &(*heap)->header.dh_next;
|
||||
}
|
||||
}
|
||||
|
||||
DISPATCH_ALLOC_NOINLINE
|
||||
static dispatch_continuation_t
|
||||
_dispatch_alloc_continuation_alloc(void)
|
||||
{
|
||||
dispatch_continuation_t cont;
|
||||
|
||||
if (likely(_dispatch_main_heap)) {
|
||||
// Start looking in the same page where we found a continuation
|
||||
// last time.
|
||||
bitmap_t *last = last_found_page();
|
||||
if (likely(last)) {
|
||||
unsigned int i;
|
||||
for (i = 0; i < BITMAPS_PER_PAGE; i++) {
|
||||
bitmap_t *cur = last + i;
|
||||
unsigned int index = bitmap_set_first_unset_bit(cur);
|
||||
if (likely(index != NO_BITS_WERE_UNSET)) {
|
||||
bitmap_t *supermap;
|
||||
unsigned int bindex;
|
||||
get_cont_and_indices_for_bitmap_and_index(cur,
|
||||
index, &cont, &supermap, &bindex);
|
||||
mark_bitmap_as_full_if_still_full(supermap, bindex,
|
||||
cur);
|
||||
return cont;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cont = _dispatch_alloc_continuation_from_heap(_dispatch_main_heap);
|
||||
if (likely(cont)) {
|
||||
return cont;
|
||||
}
|
||||
}
|
||||
return _dispatch_alloc_continuation_from_heap_slow();
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark dispatch_alloc_continuation_free
|
||||
|
||||
DISPATCH_NOINLINE
|
||||
static void
|
||||
_dispatch_alloc_maybe_madvise_page(dispatch_continuation_t c)
|
||||
{
|
||||
void *page = madvisable_page_base_for_continuation(c);
|
||||
if (!page) {
|
||||
// page can't be madvised; maybe it contains non-continuations
|
||||
return;
|
||||
}
|
||||
// Are all the continuations in this page unallocated?
|
||||
volatile bitmap_t *page_bitmaps;
|
||||
get_maps_and_indices_for_continuation((dispatch_continuation_t)page, NULL,
|
||||
NULL, (bitmap_t **)&page_bitmaps, NULL);
|
||||
unsigned int i;
|
||||
for (i = 0; i < BITMAPS_PER_PAGE; i++) {
|
||||
if (page_bitmaps[i] != 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// They are all unallocated, so we could madvise the page. Try to
|
||||
// take ownership of them all.
|
||||
int last_locked = 0;
|
||||
do {
|
||||
if (!os_atomic_cmpxchg(&page_bitmaps[last_locked], BITMAP_C(0),
|
||||
BITMAP_ALL_ONES, relaxed)) {
|
||||
// We didn't get one; since there is a cont allocated in
|
||||
// the page, we can't madvise. Give up and unlock all.
|
||||
goto unlock;
|
||||
}
|
||||
} while (++last_locked < (signed)BITMAPS_PER_PAGE);
|
||||
#if DISPATCH_DEBUG
|
||||
//fprintf(stderr, "%s: madvised page %p for cont %p (next = %p), "
|
||||
// "[%u+1]=%u bitmaps at %p\n", __func__, page, c, c->do_next,
|
||||
// last_locked-1, BITMAPS_PER_PAGE, &page_bitmaps[0]);
|
||||
// Scribble to expose use-after-free bugs
|
||||
// madvise (syscall) flushes these stores
|
||||
memset(page, DISPATCH_ALLOCATOR_SCRIBBLE, DISPATCH_ALLOCATOR_PAGE_SIZE);
|
||||
#endif
|
||||
(void)dispatch_assume_zero(madvise(page, DISPATCH_ALLOCATOR_PAGE_SIZE,
|
||||
MADV_FREE));
|
||||
|
||||
unlock:
|
||||
while (last_locked > 1) {
|
||||
page_bitmaps[--last_locked] = BITMAP_C(0);
|
||||
}
|
||||
if (last_locked) {
|
||||
os_atomic_store(&page_bitmaps[0], BITMAP_C(0), relaxed);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
DISPATCH_ALLOC_NOINLINE
|
||||
static void
|
||||
_dispatch_alloc_continuation_free(dispatch_continuation_t c)
|
||||
{
|
||||
bitmap_t *b, *s;
|
||||
unsigned int b_idx, idx;
|
||||
|
||||
c->dc_flags = 0;
|
||||
get_maps_and_indices_for_continuation(c, &s, &b_idx, &b, &idx);
|
||||
bool bitmap_now_empty = bitmap_clear_bit(b, idx, CLEAR_EXCLUSIVELY);
|
||||
if (unlikely(s)) {
|
||||
(void)bitmap_clear_bit(s, b_idx, CLEAR_NONEXCLUSIVELY);
|
||||
}
|
||||
// We only try to madvise(2) pages outside of the first page.
|
||||
// (Allocations in the first page do not have a supermap entry.)
|
||||
if (unlikely(bitmap_now_empty && s)) {
|
||||
return _dispatch_alloc_maybe_madvise_page(c);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark dispatch_alloc_init
|
||||
|
||||
#if DISPATCH_CONTINUATION_MALLOC || DISPATCH_DEBUG
|
||||
static void
|
||||
_dispatch_alloc_init(void)
|
||||
{
|
||||
// Double-check our math. These are all compile time checks and don't
|
||||
// generate code.
|
||||
|
||||
dispatch_static_assert(sizeof(bitmap_t) == BYTES_PER_BITMAP);
|
||||
dispatch_static_assert(sizeof(bitmap_t) == BYTES_PER_SUPERMAP);
|
||||
dispatch_static_assert(sizeof(struct dispatch_magazine_header_s) ==
|
||||
SIZEOF_HEADER);
|
||||
|
||||
dispatch_static_assert(sizeof(struct dispatch_continuation_s) <=
|
||||
DISPATCH_CONTINUATION_SIZE);
|
||||
|
||||
// Magazines should be the right size, so they pack neatly into an array of
|
||||
// heaps.
|
||||
dispatch_static_assert(sizeof(struct dispatch_magazine_s) ==
|
||||
BYTES_PER_MAGAZINE);
|
||||
|
||||
// The header and maps sizes should match what we computed.
|
||||
dispatch_static_assert(SIZEOF_HEADER ==
|
||||
sizeof(((struct dispatch_magazine_s *)0x0)->header));
|
||||
dispatch_static_assert(SIZEOF_MAPS ==
|
||||
sizeof(((struct dispatch_magazine_s *)0x0)->maps));
|
||||
|
||||
// The main array of continuations should start at the second page,
|
||||
// self-aligned.
|
||||
dispatch_static_assert(offsetof(struct dispatch_magazine_s, conts) %
|
||||
(CONTINUATIONS_PER_BITMAP * DISPATCH_CONTINUATION_SIZE) == 0);
|
||||
dispatch_static_assert(offsetof(struct dispatch_magazine_s, conts) ==
|
||||
DISPATCH_ALLOCATOR_PAGE_SIZE);
|
||||
|
||||
#if PACK_FIRST_PAGE_WITH_CONTINUATIONS
|
||||
// The continuations in the first page should actually fit within the first
|
||||
// page.
|
||||
dispatch_static_assert(offsetof(struct dispatch_magazine_s, fp_conts) <
|
||||
DISPATCH_ALLOCATOR_PAGE_SIZE);
|
||||
dispatch_static_assert(offsetof(struct dispatch_magazine_s, fp_conts) %
|
||||
DISPATCH_CONTINUATION_SIZE == 0);
|
||||
dispatch_static_assert(offsetof(struct dispatch_magazine_s, fp_conts) +
|
||||
sizeof(((struct dispatch_magazine_s *)0x0)->fp_conts) ==
|
||||
DISPATCH_ALLOCATOR_PAGE_SIZE);
|
||||
#endif // PACK_FIRST_PAGE_WITH_CONTINUATIONS
|
||||
// Make sure our alignment will be correct: that is, that we are correctly
|
||||
// aligning to both.
|
||||
dispatch_static_assert(ROUND_UP_TO_BITMAP_ALIGNMENT(ROUND_UP_TO_BITMAP_ALIGNMENT_AND_CONTINUATION_SIZE(1)) ==
|
||||
ROUND_UP_TO_BITMAP_ALIGNMENT_AND_CONTINUATION_SIZE(1));
|
||||
dispatch_static_assert(ROUND_UP_TO_CONTINUATION_SIZE(ROUND_UP_TO_BITMAP_ALIGNMENT_AND_CONTINUATION_SIZE(1)) ==
|
||||
ROUND_UP_TO_BITMAP_ALIGNMENT_AND_CONTINUATION_SIZE(1));
|
||||
}
|
||||
#endif // DISPATCH_CONTINUATION_MALLOC || DISPATCH_DEBUG
|
||||
|
||||
kern_return_t
|
||||
_dispatch_allocator_enumerate(task_t remote_task,
|
||||
const struct dispatch_allocator_layout_s *remote_dal,
|
||||
vm_address_t zone_address, memory_reader_t reader,
|
||||
void (^recorder)(vm_address_t, void *, size_t, bool *stop))
|
||||
{
|
||||
const size_t heap_size = remote_dal->dal_magazine_size;
|
||||
const size_t dc_size = remote_dal->dal_allocation_size;
|
||||
const size_t dc_flags_offset = remote_dal->dal_allocation_isa_offset;
|
||||
bool stop = false;
|
||||
void *heap;
|
||||
|
||||
while (zone_address) {
|
||||
// FIXME: improve this by not faulting everything and driving it through
|
||||
// the bitmap.
|
||||
kern_return_t kr = reader(remote_task, zone_address, heap_size, &heap);
|
||||
size_t offs = remote_dal->dal_first_allocation_offset;
|
||||
if (kr) return kr;
|
||||
while (offs < heap_size) {
|
||||
void *isa = *(void **)(heap + offs + dc_flags_offset);
|
||||
if (isa && isa != remote_dal->dal_deferred_free_isa) {
|
||||
recorder(zone_address + offs, heap + offs, dc_size, &stop);
|
||||
if (stop) return KERN_SUCCESS;
|
||||
}
|
||||
offs += dc_size;
|
||||
}
|
||||
zone_address = (vm_address_t)((dispatch_heap_t)heap)->header.dh_next;
|
||||
}
|
||||
|
||||
return KERN_SUCCESS;
|
||||
}
|
||||
|
||||
#endif // DISPATCH_ALLOCATOR
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark dispatch_malloc
|
||||
|
||||
#if DISPATCH_CONTINUATION_MALLOC
|
||||
|
||||
#if DISPATCH_USE_MALLOCZONE
|
||||
static malloc_zone_t *_dispatch_ccache_zone;
|
||||
|
||||
#define calloc(n, s) malloc_zone_calloc(_dispatch_ccache_zone, (n), (s))
|
||||
#define free(c) malloc_zone_free(_dispatch_ccache_zone, (c))
|
||||
|
||||
static void
|
||||
_dispatch_malloc_init(void)
|
||||
{
|
||||
_dispatch_ccache_zone = malloc_create_zone(0, 0);
|
||||
dispatch_assert(_dispatch_ccache_zone);
|
||||
malloc_set_zone_name(_dispatch_ccache_zone, "DispatchContinuations");
|
||||
}
|
||||
#else
|
||||
#define _dispatch_malloc_init() ((void)0)
|
||||
#endif // DISPATCH_USE_MALLOCZONE
|
||||
|
||||
static dispatch_continuation_t
|
||||
_dispatch_malloc_continuation_alloc(void)
|
||||
{
|
||||
dispatch_continuation_t dc;
|
||||
size_t alloc_size = ROUND_UP_TO_CACHELINE_SIZE(sizeof(*dc));
|
||||
while (unlikely(!(dc = calloc(1, alloc_size)))) {
|
||||
_dispatch_temporary_resource_shortage();
|
||||
}
|
||||
return dc;
|
||||
}
|
||||
|
||||
static inline void
|
||||
_dispatch_malloc_continuation_free(dispatch_continuation_t c)
|
||||
{
|
||||
free(c);
|
||||
}
|
||||
#endif // DISPATCH_CONTINUATION_MALLOC
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark dispatch_continuation_alloc
|
||||
|
||||
#if DISPATCH_ALLOCATOR
|
||||
#if DISPATCH_CONTINUATION_MALLOC
|
||||
#if !DISPATCH_USE_NANOZONE
|
||||
#define malloc_engaged_nano() false
|
||||
#endif // !DISPATCH_USE_NANOZONE
|
||||
DISPATCH_STATIC_GLOBAL(bool _dispatch_use_dispatch_alloc);
|
||||
#else
|
||||
#define _dispatch_use_dispatch_alloc 1
|
||||
#endif // DISPATCH_CONTINUATION_MALLOC
|
||||
#endif // DISPATCH_ALLOCATOR
|
||||
|
||||
#if (DISPATCH_ALLOCATOR && (DISPATCH_CONTINUATION_MALLOC || DISPATCH_DEBUG)) \
|
||||
|| (DISPATCH_CONTINUATION_MALLOC && DISPATCH_USE_MALLOCZONE)
|
||||
|
||||
DISPATCH_STATIC_GLOBAL(dispatch_once_t _dispatch_continuation_alloc_init_pred);
|
||||
|
||||
static void
|
||||
_dispatch_continuation_alloc_init(void *ctxt DISPATCH_UNUSED)
|
||||
{
|
||||
#if DISPATCH_ALLOCATOR
|
||||
#if DISPATCH_CONTINUATION_MALLOC
|
||||
bool use_dispatch_alloc = !malloc_engaged_nano();
|
||||
char *e = getenv("LIBDISPATCH_CONTINUATION_ALLOCATOR");
|
||||
if (e) {
|
||||
use_dispatch_alloc = atoi(e);
|
||||
}
|
||||
_dispatch_use_dispatch_alloc = use_dispatch_alloc;
|
||||
#endif // DISPATCH_CONTINUATION_MALLOC
|
||||
if (_dispatch_use_dispatch_alloc)
|
||||
return _dispatch_alloc_init();
|
||||
#endif // DISPATCH_ALLOCATOR
|
||||
#if DISPATCH_CONTINUATION_MALLOC
|
||||
return _dispatch_malloc_init();
|
||||
#endif // DISPATCH_ALLOCATOR
|
||||
}
|
||||
|
||||
static inline void
|
||||
_dispatch_continuation_alloc_once(void)
|
||||
{
|
||||
dispatch_once_f(&_dispatch_continuation_alloc_init_pred,
|
||||
NULL, _dispatch_continuation_alloc_init);
|
||||
}
|
||||
#else
|
||||
static inline void _dispatch_continuation_alloc_once(void) {}
|
||||
#endif // DISPATCH_ALLOCATOR ... || DISPATCH_CONTINUATION_MALLOC ...
|
||||
|
||||
dispatch_continuation_t
|
||||
_dispatch_continuation_alloc_from_heap(void)
|
||||
{
|
||||
_dispatch_continuation_alloc_once();
|
||||
#if DISPATCH_ALLOCATOR
|
||||
if (_dispatch_use_dispatch_alloc)
|
||||
return _dispatch_alloc_continuation_alloc();
|
||||
#endif
|
||||
#if DISPATCH_CONTINUATION_MALLOC
|
||||
return _dispatch_malloc_continuation_alloc();
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
_dispatch_continuation_free_to_heap(dispatch_continuation_t c)
|
||||
{
|
||||
#if DISPATCH_ALLOCATOR
|
||||
if (_dispatch_use_dispatch_alloc)
|
||||
return _dispatch_alloc_continuation_free(c);
|
||||
#endif
|
||||
#if DISPATCH_CONTINUATION_MALLOC
|
||||
return _dispatch_malloc_continuation_free(c);
|
||||
#endif
|
||||
}
|
||||
296
Telegram/ThirdParty/dispatch/src/allocator_internal.h
vendored
Normal file
296
Telegram/ThirdParty/dispatch/src/allocator_internal.h
vendored
Normal file
@@ -0,0 +1,296 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2013 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
/*
|
||||
* IMPORTANT: This header file describes INTERNAL interfaces to libdispatch
|
||||
* which are subject to change in future releases of Mac OS X. Any applications
|
||||
* relying on these interfaces WILL break.
|
||||
*/
|
||||
|
||||
#ifndef __DISPATCH_ALLOCATOR_INTERNAL__
|
||||
#define __DISPATCH_ALLOCATOR_INTERNAL__
|
||||
|
||||
#ifndef DISPATCH_ALLOCATOR
|
||||
#if TARGET_OS_MAC && (defined(__LP64__) || TARGET_OS_IPHONE)
|
||||
#define DISPATCH_ALLOCATOR 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef DISPATCH_USE_NANOZONE
|
||||
#if TARGET_OS_MAC && defined(__LP64__)
|
||||
#define DISPATCH_USE_NANOZONE 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef DISPATCH_USE_MALLOCZONE
|
||||
#if (TARGET_OS_MAC && !DISPATCH_USE_NANOZONE) || \
|
||||
(!TARGET_OS_MAC && HAVE_MALLOC_CREATE_ZONE)
|
||||
#define DISPATCH_USE_MALLOCZONE 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef DISPATCH_CONTINUATION_MALLOC
|
||||
#if DISPATCH_USE_NANOZONE || !DISPATCH_ALLOCATOR
|
||||
#define DISPATCH_CONTINUATION_MALLOC 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !DISPATCH_ALLOCATOR && !DISPATCH_CONTINUATION_MALLOC
|
||||
#error Invalid allocator configuration
|
||||
#endif
|
||||
|
||||
#if DISPATCH_ALLOCATOR && DISPATCH_CONTINUATION_MALLOC
|
||||
#define DISPATCH_ALLOC_NOINLINE DISPATCH_NOINLINE
|
||||
#else
|
||||
#define DISPATCH_ALLOC_NOINLINE
|
||||
#endif
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark DISPATCH_ALLOCATOR
|
||||
|
||||
#if DISPATCH_ALLOCATOR
|
||||
|
||||
// Configuration here!
|
||||
#define NUM_CPU dispatch_hw_config(logical_cpus)
|
||||
#define MAGAZINES_PER_HEAP (NUM_CPU)
|
||||
|
||||
// Do you care about compaction or performance?
|
||||
#if TARGET_OS_IPHONE
|
||||
#define PACK_FIRST_PAGE_WITH_CONTINUATIONS 1
|
||||
#else
|
||||
#define PACK_FIRST_PAGE_WITH_CONTINUATIONS 0
|
||||
#endif
|
||||
|
||||
#ifndef PAGE_MAX_SIZE
|
||||
#define PAGE_MAX_SIZE PAGE_SIZE
|
||||
#endif
|
||||
#ifndef PAGE_MAX_MASK
|
||||
#define PAGE_MAX_MASK PAGE_MASK
|
||||
#endif
|
||||
#define DISPATCH_ALLOCATOR_PAGE_SIZE PAGE_MAX_SIZE
|
||||
#define DISPATCH_ALLOCATOR_PAGE_MASK PAGE_MAX_MASK
|
||||
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
#define PAGES_PER_MAGAZINE 64
|
||||
#else
|
||||
#define PAGES_PER_MAGAZINE 512
|
||||
#endif
|
||||
|
||||
// Use the largest type your platform is comfortable doing atomic ops with.
|
||||
// TODO: rdar://11477843
|
||||
typedef unsigned long bitmap_t;
|
||||
#if DISPATCH_SIZEOF_PTR == 8
|
||||
#define BYTES_PER_BITMAP 8
|
||||
#else
|
||||
#define BYTES_PER_BITMAP 4
|
||||
#endif
|
||||
|
||||
#define BITMAP_C(v) ((bitmap_t)(v))
|
||||
#define BITMAP_ALL_ONES (~BITMAP_C(0))
|
||||
|
||||
// Stop configuring.
|
||||
|
||||
#define CONTINUATIONS_PER_BITMAP (BYTES_PER_BITMAP * 8)
|
||||
#define BITMAPS_PER_SUPERMAP (BYTES_PER_SUPERMAP * 8)
|
||||
|
||||
#define BYTES_PER_MAGAZINE (PAGES_PER_MAGAZINE * DISPATCH_ALLOCATOR_PAGE_SIZE)
|
||||
#define CONSUMED_BYTES_PER_BITMAP (BYTES_PER_BITMAP + \
|
||||
(DISPATCH_CONTINUATION_SIZE * CONTINUATIONS_PER_BITMAP))
|
||||
|
||||
#define BYTES_PER_SUPERMAP BYTES_PER_BITMAP
|
||||
#define CONSUMED_BYTES_PER_SUPERMAP (BYTES_PER_SUPERMAP + \
|
||||
(BITMAPS_PER_SUPERMAP * CONSUMED_BYTES_PER_BITMAP))
|
||||
|
||||
#define BYTES_PER_HEAP (BYTES_PER_MAGAZINE * MAGAZINES_PER_HEAP)
|
||||
|
||||
#define BYTES_PER_PAGE DISPATCH_ALLOCATOR_PAGE_SIZE
|
||||
#define CONTINUATIONS_PER_PAGE (BYTES_PER_PAGE / DISPATCH_CONTINUATION_SIZE)
|
||||
#define BITMAPS_PER_PAGE (CONTINUATIONS_PER_PAGE / CONTINUATIONS_PER_BITMAP)
|
||||
|
||||
// Assumption: metadata will be only in the first page.
|
||||
#define SUPERMAPS_PER_MAGAZINE ((BYTES_PER_MAGAZINE - BYTES_PER_PAGE) / \
|
||||
CONSUMED_BYTES_PER_SUPERMAP)
|
||||
#define BITMAPS_PER_MAGAZINE (SUPERMAPS_PER_MAGAZINE * BITMAPS_PER_SUPERMAP)
|
||||
#define CONTINUATIONS_PER_MAGAZINE \
|
||||
(BITMAPS_PER_MAGAZINE * CONTINUATIONS_PER_BITMAP)
|
||||
|
||||
#define HEAP_MASK (~(uintptr_t)(BYTES_PER_HEAP - 1))
|
||||
#define MAGAZINE_MASK (~(uintptr_t)(BYTES_PER_MAGAZINE - 1))
|
||||
|
||||
// this will round up such that first_bitmap_in_same_page() can mask the address
|
||||
// of a bitmap_t in the maps to obtain the first bitmap for that same page
|
||||
#define ROUND_UP_TO_BITMAP_ALIGNMENT(x) \
|
||||
(((x) + ((BITMAPS_PER_PAGE * BYTES_PER_BITMAP) - 1u)) & \
|
||||
~((BITMAPS_PER_PAGE * BYTES_PER_BITMAP) - 1u))
|
||||
// Since these are both powers of two, we end up with not only the max alignment,
|
||||
// but happily the least common multiple, which will be the greater of the two.
|
||||
#define ROUND_UP_TO_BITMAP_ALIGNMENT_AND_CONTINUATION_SIZE(x) (ROUND_UP_TO_CONTINUATION_SIZE(ROUND_UP_TO_BITMAP_ALIGNMENT(x)))
|
||||
#define PADDING_TO_BITMAP_ALIGNMENT_AND_CONTINUATION_SIZE(x) (ROUND_UP_TO_BITMAP_ALIGNMENT_AND_CONTINUATION_SIZE(x) - (x))
|
||||
|
||||
#define PADDING_TO_CONTINUATION_SIZE(x) (ROUND_UP_TO_CONTINUATION_SIZE(x) - (x))
|
||||
|
||||
#if DISPATCH_SIZEOF_PTR == 8
|
||||
#define SIZEOF_HEADER 16
|
||||
#else
|
||||
#define SIZEOF_HEADER 8
|
||||
#endif
|
||||
|
||||
#define SIZEOF_SUPERMAPS (BYTES_PER_SUPERMAP * SUPERMAPS_PER_MAGAZINE)
|
||||
#define SIZEOF_MAPS (BYTES_PER_BITMAP * BITMAPS_PER_SUPERMAP * \
|
||||
SUPERMAPS_PER_MAGAZINE)
|
||||
|
||||
// header is expected to end on supermap's required alignment
|
||||
#define HEADER_TO_SUPERMAPS_PADDING 0
|
||||
// we want to align the maps to a continuation size, but we must also have proper padding
|
||||
// so that we can perform first_bitmap_in_same_page()
|
||||
#define SUPERMAPS_TO_MAPS_PADDING (PADDING_TO_BITMAP_ALIGNMENT_AND_CONTINUATION_SIZE( \
|
||||
SIZEOF_SUPERMAPS + HEADER_TO_SUPERMAPS_PADDING + SIZEOF_HEADER))
|
||||
|
||||
#define MAPS_TO_FPMAPS_PADDING (PADDING_TO_CONTINUATION_SIZE(SIZEOF_MAPS))
|
||||
|
||||
#define BYTES_LEFT_IN_FIRST_PAGE (BYTES_PER_PAGE - \
|
||||
(SIZEOF_HEADER + HEADER_TO_SUPERMAPS_PADDING + SIZEOF_SUPERMAPS + \
|
||||
SUPERMAPS_TO_MAPS_PADDING + SIZEOF_MAPS + MAPS_TO_FPMAPS_PADDING))
|
||||
|
||||
#if PACK_FIRST_PAGE_WITH_CONTINUATIONS
|
||||
|
||||
#define FULL_BITMAPS_IN_FIRST_PAGE \
|
||||
(BYTES_LEFT_IN_FIRST_PAGE / CONSUMED_BYTES_PER_BITMAP)
|
||||
#define REMAINDER_IN_FIRST_PAGE (BYTES_LEFT_IN_FIRST_PAGE - \
|
||||
(FULL_BITMAPS_IN_FIRST_PAGE * CONSUMED_BYTES_PER_BITMAP) - \
|
||||
(FULL_BITMAPS_IN_FIRST_PAGE ? 0 : \
|
||||
ROUND_UP_TO_CONTINUATION_SIZE(BYTES_PER_BITMAP)))
|
||||
|
||||
#define REMAINDERED_CONTINUATIONS_IN_FIRST_PAGE \
|
||||
(REMAINDER_IN_FIRST_PAGE / DISPATCH_CONTINUATION_SIZE)
|
||||
#define CONTINUATIONS_IN_FIRST_PAGE (FULL_BITMAPS_IN_FIRST_PAGE * \
|
||||
CONTINUATIONS_PER_BITMAP) + REMAINDERED_CONTINUATIONS_IN_FIRST_PAGE
|
||||
#define BITMAPS_IN_FIRST_PAGE (FULL_BITMAPS_IN_FIRST_PAGE + \
|
||||
(REMAINDERED_CONTINUATIONS_IN_FIRST_PAGE == 0 ? 0 : 1))
|
||||
|
||||
#define FPMAPS_TO_FPCONTS_PADDING (PADDING_TO_CONTINUATION_SIZE(\
|
||||
BYTES_PER_BITMAP * BITMAPS_IN_FIRST_PAGE))
|
||||
|
||||
#else // PACK_FIRST_PAGE_WITH_CONTINUATIONS
|
||||
|
||||
#define MAPS_TO_CONTS_PADDING BYTES_LEFT_IN_FIRST_PAGE
|
||||
|
||||
#endif // PACK_FIRST_PAGE_WITH_CONTINUATIONS
|
||||
|
||||
#define AFTER_CONTS_PADDING (BYTES_PER_MAGAZINE - (BYTES_PER_PAGE + \
|
||||
(DISPATCH_CONTINUATION_SIZE * CONTINUATIONS_PER_MAGAZINE)))
|
||||
|
||||
// This is the object our allocator allocates: a chunk of memory rounded up
|
||||
// from sizeof(struct dispatch_continuation_s) to the cacheline size, so
|
||||
// unrelated continuations don't share cachelines. It'd be nice if
|
||||
// dispatch_continuation_s included this rounding/padding, but it doesn't.
|
||||
typedef char padded_continuation[DISPATCH_CONTINUATION_SIZE];
|
||||
|
||||
// A dispatch_heap_t is the base address of an array of dispatch_magazine_s,
|
||||
// one magazine per CPU.
|
||||
typedef struct dispatch_magazine_s * dispatch_heap_t;
|
||||
|
||||
struct dispatch_magazine_header_s {
|
||||
// Link to the next heap in the chain. Only used in magazine 0's header
|
||||
dispatch_heap_t dh_next;
|
||||
|
||||
// Points to the first bitmap in the page where this CPU successfully
|
||||
// allocated a continuation last time. Only used in the first heap.
|
||||
bitmap_t *last_found_page;
|
||||
};
|
||||
|
||||
// A magazine is a complex data structure. It must be exactly
|
||||
// PAGES_PER_MAGAZINE * PAGE_SIZE bytes long, and that value must be a
|
||||
// power of 2. (See magazine_for_continuation()).
|
||||
struct dispatch_magazine_s {
|
||||
// See above.
|
||||
struct dispatch_magazine_header_s header;
|
||||
|
||||
// Align supermaps as needed.
|
||||
#if HEADER_TO_SUPERMAPS_PADDING > 0
|
||||
char _pad0[HEADER_TO_SUPERMAPS_PADDING];
|
||||
#endif
|
||||
|
||||
// Second-level bitmap; each set bit means a bitmap_t in maps[][]
|
||||
// is completely full (and can be skipped while searching).
|
||||
bitmap_t supermaps[SUPERMAPS_PER_MAGAZINE];
|
||||
|
||||
// Align maps to a cacheline.
|
||||
#if SUPERMAPS_TO_MAPS_PADDING > 0
|
||||
char _pad1[SUPERMAPS_TO_MAPS_PADDING];
|
||||
#endif
|
||||
|
||||
// Each bit in maps[][] is the free/used state of a member of conts[][][].
|
||||
bitmap_t maps[SUPERMAPS_PER_MAGAZINE][BITMAPS_PER_SUPERMAP];
|
||||
|
||||
// Align fp_maps to a cacheline.
|
||||
#if MAPS_TO_FPMAPS_PADDING > 0
|
||||
char _pad2[MAPS_TO_FPMAPS_PADDING];
|
||||
#endif
|
||||
|
||||
#if PACK_FIRST_PAGE_WITH_CONTINUATIONS
|
||||
// Bitmaps for the continuations that live in the first page, which
|
||||
// are treated specially (they have faster search code).
|
||||
bitmap_t fp_maps[BITMAPS_IN_FIRST_PAGE];
|
||||
|
||||
// Align fp_conts to cacheline.
|
||||
#if FPMAPS_TO_FPCONTS_PADDING > 0
|
||||
char _pad3[FPMAPS_TO_FPCONTS_PADDING];
|
||||
#endif
|
||||
|
||||
// Continuations that live in the first page.
|
||||
padded_continuation fp_conts[CONTINUATIONS_IN_FIRST_PAGE];
|
||||
|
||||
#else // PACK_FIRST_PAGE_WITH_CONTINUATIONS
|
||||
|
||||
#if MAPS_TO_CONTS_PADDING > 0
|
||||
char _pad4[MAPS_TO_CONTS_PADDING];
|
||||
#endif
|
||||
#endif // PACK_FIRST_PAGE_WITH_CONTINUATIONS
|
||||
|
||||
// This is the big array of continuations.
|
||||
// This must start on a page boundary.
|
||||
padded_continuation conts[SUPERMAPS_PER_MAGAZINE][BITMAPS_PER_SUPERMAP]
|
||||
[CONTINUATIONS_PER_BITMAP];
|
||||
|
||||
// Fill the unused space to exactly BYTES_PER_MAGAZINE
|
||||
#if AFTER_CONTS_PADDING > 0
|
||||
char _pad5[AFTER_CONTS_PADDING];
|
||||
#endif
|
||||
};
|
||||
|
||||
#if DISPATCH_DEBUG
|
||||
#define DISPATCH_ALLOCATOR_SCRIBBLE ((uintptr_t)0xAFAFAFAFAFAFAFAF)
|
||||
#endif
|
||||
|
||||
|
||||
kern_return_t _dispatch_allocator_enumerate(task_t remote_task,
|
||||
const struct dispatch_allocator_layout_s *remote_allocator_layout,
|
||||
vm_address_t zone_address, memory_reader_t reader,
|
||||
void (^recorder)(vm_address_t, void *, size_t , bool *stop));
|
||||
|
||||
#endif // DISPATCH_ALLOCATOR
|
||||
|
||||
#if DISPATCH_ALLOCATOR
|
||||
extern dispatch_heap_t _dispatch_main_heap;
|
||||
#endif
|
||||
|
||||
#endif // __DISPATCH_ALLOCATOR_INTERNAL__
|
||||
368
Telegram/ThirdParty/dispatch/src/apply.c
vendored
Normal file
368
Telegram/ThirdParty/dispatch/src/apply.c
vendored
Normal file
@@ -0,0 +1,368 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2013 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
typedef void (*dispatch_apply_function_t)(void *, size_t);
|
||||
static char const * const _dispatch_apply_key = "apply";
|
||||
|
||||
#define DISPATCH_APPLY_INVOKE_REDIRECT 0x1
|
||||
#define DISPATCH_APPLY_INVOKE_WAIT 0x2
|
||||
|
||||
DISPATCH_ALWAYS_INLINE
|
||||
static inline void
|
||||
_dispatch_apply_invoke2(dispatch_apply_t da, long invoke_flags)
|
||||
{
|
||||
size_t const iter = da->da_iterations;
|
||||
size_t idx, done = 0;
|
||||
|
||||
idx = os_atomic_inc_orig2o(da, da_index, acquire);
|
||||
if (unlikely(idx >= iter)) goto out;
|
||||
|
||||
// da_dc is only safe to access once the 'index lock' has been acquired
|
||||
dispatch_apply_function_t const func = (void *)da->da_dc->dc_func;
|
||||
void *const da_ctxt = da->da_dc->dc_ctxt;
|
||||
|
||||
_dispatch_perfmon_workitem_dec(); // this unit executes many items
|
||||
|
||||
// Handle nested dispatch_apply rdar://problem/9294578
|
||||
dispatch_thread_context_s apply_ctxt = {
|
||||
.dtc_key = _dispatch_apply_key,
|
||||
.dtc_apply_nesting = da->da_nested,
|
||||
};
|
||||
_dispatch_thread_context_push(&apply_ctxt);
|
||||
|
||||
dispatch_thread_frame_s dtf;
|
||||
dispatch_priority_t old_dbp = 0;
|
||||
if (invoke_flags & DISPATCH_APPLY_INVOKE_REDIRECT) {
|
||||
dispatch_queue_t dq = da->da_dc->dc_data;
|
||||
_dispatch_thread_frame_push(&dtf, dq);
|
||||
old_dbp = _dispatch_set_basepri(dq->dq_priority);
|
||||
}
|
||||
dispatch_invoke_flags_t flags = da->da_flags;
|
||||
|
||||
// Striding is the responsibility of the caller.
|
||||
do {
|
||||
dispatch_invoke_with_autoreleasepool(flags, {
|
||||
_dispatch_client_callout2(da_ctxt, idx, func);
|
||||
_dispatch_perfmon_workitem_inc();
|
||||
done++;
|
||||
idx = os_atomic_inc_orig2o(da, da_index, relaxed);
|
||||
});
|
||||
} while (likely(idx < iter));
|
||||
|
||||
if (invoke_flags & DISPATCH_APPLY_INVOKE_REDIRECT) {
|
||||
_dispatch_reset_basepri(old_dbp);
|
||||
_dispatch_thread_frame_pop(&dtf);
|
||||
}
|
||||
|
||||
_dispatch_thread_context_pop(&apply_ctxt);
|
||||
|
||||
// The thread that finished the last workitem wakes up the possibly waiting
|
||||
// thread that called dispatch_apply. They could be one and the same.
|
||||
if (!os_atomic_sub2o(da, da_todo, done, release)) {
|
||||
_dispatch_thread_event_signal(&da->da_event);
|
||||
}
|
||||
out:
|
||||
if (invoke_flags & DISPATCH_APPLY_INVOKE_WAIT) {
|
||||
_dispatch_thread_event_wait(&da->da_event);
|
||||
_dispatch_thread_event_destroy(&da->da_event);
|
||||
}
|
||||
if (os_atomic_dec2o(da, da_thr_cnt, release) == 0) {
|
||||
#if DISPATCH_INTROSPECTION
|
||||
_dispatch_continuation_free(da->da_dc);
|
||||
#endif
|
||||
_dispatch_continuation_free((dispatch_continuation_t)da);
|
||||
}
|
||||
}
|
||||
|
||||
DISPATCH_NOINLINE
|
||||
void
|
||||
_dispatch_apply_invoke(void *ctxt)
|
||||
{
|
||||
_dispatch_apply_invoke2(ctxt, 0);
|
||||
}
|
||||
|
||||
DISPATCH_NOINLINE
|
||||
static void
|
||||
_dispatch_apply_invoke_and_wait(void *ctxt)
|
||||
{
|
||||
_dispatch_apply_invoke2(ctxt, DISPATCH_APPLY_INVOKE_WAIT);
|
||||
_dispatch_perfmon_workitem_inc();
|
||||
}
|
||||
|
||||
DISPATCH_NOINLINE
|
||||
void
|
||||
_dispatch_apply_redirect_invoke(void *ctxt)
|
||||
{
|
||||
_dispatch_apply_invoke2(ctxt, DISPATCH_APPLY_INVOKE_REDIRECT);
|
||||
}
|
||||
|
||||
DISPATCH_ALWAYS_INLINE
|
||||
static inline dispatch_invoke_flags_t
|
||||
_dispatch_apply_autorelease_frequency(dispatch_queue_t dq)
|
||||
{
|
||||
dispatch_invoke_flags_t qaf = 0;
|
||||
|
||||
while (dq && !qaf) {
|
||||
qaf = _dispatch_queue_autorelease_frequency(dq);
|
||||
dq = dq->do_targetq;
|
||||
}
|
||||
return qaf;
|
||||
}
|
||||
|
||||
DISPATCH_NOINLINE
|
||||
static void
|
||||
_dispatch_apply_serial(void *ctxt)
|
||||
{
|
||||
dispatch_apply_t da = (dispatch_apply_t)ctxt;
|
||||
dispatch_continuation_t dc = da->da_dc;
|
||||
size_t const iter = da->da_iterations;
|
||||
dispatch_invoke_flags_t flags;
|
||||
size_t idx = 0;
|
||||
|
||||
_dispatch_perfmon_workitem_dec(); // this unit executes many items
|
||||
flags = _dispatch_apply_autorelease_frequency(dc->dc_data);
|
||||
do {
|
||||
dispatch_invoke_with_autoreleasepool(flags, {
|
||||
_dispatch_client_callout2(dc->dc_ctxt, idx, (void*)dc->dc_func);
|
||||
_dispatch_perfmon_workitem_inc();
|
||||
});
|
||||
} while (++idx < iter);
|
||||
|
||||
#if DISPATCH_INTROSPECTION
|
||||
_dispatch_continuation_free(da->da_dc);
|
||||
#endif
|
||||
_dispatch_continuation_free((dispatch_continuation_t)da);
|
||||
}
|
||||
|
||||
DISPATCH_ALWAYS_INLINE
|
||||
static inline void
|
||||
_dispatch_apply_f(dispatch_queue_global_t dq, dispatch_apply_t da,
|
||||
dispatch_function_t func)
|
||||
{
|
||||
int32_t i = 0;
|
||||
dispatch_continuation_t head = NULL, tail = NULL;
|
||||
pthread_priority_t pp = _dispatch_get_priority();
|
||||
|
||||
// The current thread does not need a continuation
|
||||
int32_t continuation_cnt = da->da_thr_cnt - 1;
|
||||
|
||||
dispatch_assert(continuation_cnt);
|
||||
|
||||
for (i = 0; i < continuation_cnt; i++) {
|
||||
dispatch_continuation_t next = _dispatch_continuation_alloc();
|
||||
uintptr_t dc_flags = DC_FLAG_CONSUME;
|
||||
|
||||
_dispatch_continuation_init_f(next, dq, da, func,
|
||||
DISPATCH_BLOCK_HAS_PRIORITY, dc_flags);
|
||||
next->dc_priority = pp | _PTHREAD_PRIORITY_ENFORCE_FLAG;
|
||||
next->do_next = head;
|
||||
head = next;
|
||||
|
||||
if (!tail) {
|
||||
tail = next;
|
||||
}
|
||||
}
|
||||
|
||||
_dispatch_thread_event_init(&da->da_event);
|
||||
// FIXME: dq may not be the right queue for the priority of `head`
|
||||
_dispatch_trace_item_push_list(dq, head, tail);
|
||||
_dispatch_root_queue_push_inline(dq, head, tail, continuation_cnt);
|
||||
// Call the first element directly
|
||||
_dispatch_apply_invoke_and_wait(da);
|
||||
}
|
||||
|
||||
DISPATCH_ALWAYS_INLINE DISPATCH_WARN_RESULT
|
||||
static inline int32_t
|
||||
_dispatch_queue_try_reserve_apply_width(dispatch_queue_t dq, int32_t da_width)
|
||||
{
|
||||
uint64_t old_state, new_state;
|
||||
int32_t width;
|
||||
|
||||
if (unlikely(dq->dq_width == 1)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
os_atomic_rmw_loop2o(dq, dq_state, old_state, new_state, relaxed, {
|
||||
width = (int32_t)_dq_state_available_width(old_state);
|
||||
if (unlikely(!width)) {
|
||||
os_atomic_rmw_loop_give_up(return 0);
|
||||
}
|
||||
if (width > da_width) {
|
||||
width = da_width;
|
||||
}
|
||||
new_state = old_state + (uint64_t)width * DISPATCH_QUEUE_WIDTH_INTERVAL;
|
||||
});
|
||||
return width;
|
||||
}
|
||||
|
||||
DISPATCH_ALWAYS_INLINE
|
||||
static inline void
|
||||
_dispatch_queue_relinquish_width(dispatch_queue_t top_dq,
|
||||
dispatch_queue_t stop_dq, int32_t da_width)
|
||||
{
|
||||
uint64_t delta = (uint64_t)da_width * DISPATCH_QUEUE_WIDTH_INTERVAL;
|
||||
dispatch_queue_t dq = top_dq;
|
||||
|
||||
while (dq != stop_dq) {
|
||||
os_atomic_sub2o(dq, dq_state, delta, relaxed);
|
||||
dq = dq->do_targetq;
|
||||
}
|
||||
}
|
||||
|
||||
DISPATCH_NOINLINE
|
||||
static void
|
||||
_dispatch_apply_redirect(void *ctxt)
|
||||
{
|
||||
dispatch_apply_t da = (dispatch_apply_t)ctxt;
|
||||
int32_t da_width = da->da_thr_cnt - 1;
|
||||
dispatch_queue_t top_dq = da->da_dc->dc_data, dq = top_dq;
|
||||
|
||||
do {
|
||||
int32_t width = _dispatch_queue_try_reserve_apply_width(dq, da_width);
|
||||
|
||||
if (unlikely(da_width > width)) {
|
||||
int32_t excess = da_width - width;
|
||||
_dispatch_queue_relinquish_width(top_dq, dq, excess);
|
||||
da_width = width;
|
||||
if (unlikely(!da_width)) {
|
||||
return _dispatch_apply_serial(da);
|
||||
}
|
||||
da->da_thr_cnt -= excess;
|
||||
}
|
||||
if (!da->da_flags) {
|
||||
// find first queue in descending target queue order that has
|
||||
// an autorelease frequency set, and use that as the frequency for
|
||||
// this continuation.
|
||||
da->da_flags = _dispatch_queue_autorelease_frequency(dq);
|
||||
}
|
||||
dq = dq->do_targetq;
|
||||
} while (unlikely(dq->do_targetq));
|
||||
|
||||
_dispatch_apply_f(upcast(dq)._dgq, da, _dispatch_apply_redirect_invoke);
|
||||
_dispatch_queue_relinquish_width(top_dq, dq, da_width);
|
||||
}
|
||||
|
||||
#define DISPATCH_APPLY_MAX UINT16_MAX // must be < sqrt(SIZE_MAX)
|
||||
|
||||
DISPATCH_ALWAYS_INLINE
|
||||
static inline dispatch_queue_global_t
|
||||
_dispatch_apply_root_queue(dispatch_queue_t dq)
|
||||
{
|
||||
if (dq) {
|
||||
while (unlikely(dq->do_targetq)) {
|
||||
dq = dq->do_targetq;
|
||||
}
|
||||
// if the current root queue is a pthread root queue, select it
|
||||
if (!_dispatch_is_in_root_queues_array(dq)) {
|
||||
return upcast(dq)._dgq;
|
||||
}
|
||||
}
|
||||
|
||||
pthread_priority_t pp = _dispatch_get_priority();
|
||||
dispatch_qos_t qos = _dispatch_qos_from_pp(pp);
|
||||
return _dispatch_get_root_queue(qos ? qos : DISPATCH_QOS_DEFAULT, false);
|
||||
}
|
||||
|
||||
DISPATCH_NOINLINE
|
||||
void
|
||||
dispatch_apply_f(size_t iterations, dispatch_queue_t _dq, void *ctxt,
|
||||
void (*func)(void *, size_t))
|
||||
{
|
||||
if (unlikely(iterations == 0)) {
|
||||
return;
|
||||
}
|
||||
dispatch_thread_context_t dtctxt =
|
||||
_dispatch_thread_context_find(_dispatch_apply_key);
|
||||
size_t nested = dtctxt ? dtctxt->dtc_apply_nesting : 0;
|
||||
dispatch_queue_t old_dq = _dispatch_queue_get_current();
|
||||
dispatch_queue_t dq;
|
||||
|
||||
if (likely(_dq == DISPATCH_APPLY_AUTO)) {
|
||||
dq = _dispatch_apply_root_queue(old_dq)->_as_dq;
|
||||
} else {
|
||||
dq = _dq; // silence clang Nullability complaints
|
||||
}
|
||||
dispatch_qos_t qos = _dispatch_priority_qos(dq->dq_priority) ?:
|
||||
_dispatch_priority_fallback_qos(dq->dq_priority);
|
||||
if (unlikely(dq->do_targetq)) {
|
||||
// if the queue passed-in is not a root queue, use the current QoS
|
||||
// since the caller participates in the work anyway
|
||||
qos = _dispatch_qos_from_pp(_dispatch_get_priority());
|
||||
}
|
||||
int32_t thr_cnt = (int32_t)_dispatch_qos_max_parallelism(qos,
|
||||
DISPATCH_MAX_PARALLELISM_ACTIVE);
|
||||
|
||||
if (likely(!nested)) {
|
||||
nested = iterations;
|
||||
} else {
|
||||
thr_cnt = nested < (size_t)thr_cnt ? thr_cnt / (int32_t)nested : 1;
|
||||
nested = nested < DISPATCH_APPLY_MAX && iterations < DISPATCH_APPLY_MAX
|
||||
? nested * iterations : DISPATCH_APPLY_MAX;
|
||||
}
|
||||
if (iterations < (size_t)thr_cnt) {
|
||||
thr_cnt = (int32_t)iterations;
|
||||
}
|
||||
struct dispatch_continuation_s dc = {
|
||||
.dc_func = (void*)func,
|
||||
.dc_ctxt = ctxt,
|
||||
.dc_data = dq,
|
||||
};
|
||||
dispatch_apply_t da = (__typeof__(da))_dispatch_continuation_alloc();
|
||||
da->da_index = 0;
|
||||
da->da_todo = iterations;
|
||||
da->da_iterations = iterations;
|
||||
da->da_nested = nested;
|
||||
da->da_thr_cnt = thr_cnt;
|
||||
#if DISPATCH_INTROSPECTION
|
||||
da->da_dc = _dispatch_continuation_alloc();
|
||||
*da->da_dc = dc;
|
||||
da->da_dc->dc_flags = DC_FLAG_ALLOCATED;
|
||||
#else
|
||||
da->da_dc = &dc;
|
||||
#endif
|
||||
da->da_flags = 0;
|
||||
|
||||
if (unlikely(dq->dq_width == 1 || thr_cnt <= 1)) {
|
||||
return dispatch_sync_f(dq, da, _dispatch_apply_serial);
|
||||
}
|
||||
if (unlikely(dq->do_targetq)) {
|
||||
if (unlikely(dq == old_dq)) {
|
||||
return dispatch_sync_f(dq, da, _dispatch_apply_serial);
|
||||
} else {
|
||||
return dispatch_sync_f(dq, da, _dispatch_apply_redirect);
|
||||
}
|
||||
}
|
||||
|
||||
dispatch_thread_frame_s dtf;
|
||||
_dispatch_thread_frame_push(&dtf, dq);
|
||||
_dispatch_apply_f(upcast(dq)._dgq, da, _dispatch_apply_invoke);
|
||||
_dispatch_thread_frame_pop(&dtf);
|
||||
}
|
||||
|
||||
#ifdef __BLOCKS__
|
||||
void
|
||||
dispatch_apply(size_t iterations, dispatch_queue_t dq, void (^work)(size_t))
|
||||
{
|
||||
dispatch_apply_f(iterations, dq, work,
|
||||
(dispatch_apply_function_t)_dispatch_Block_invoke(work));
|
||||
}
|
||||
#endif
|
||||
128
Telegram/ThirdParty/dispatch/src/benchmark.c
vendored
Normal file
128
Telegram/ThirdParty/dispatch/src/benchmark.c
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2013 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
struct __dispatch_benchmark_data_s {
|
||||
#if HAVE_MACH_ABSOLUTE_TIME
|
||||
mach_timebase_info_data_t tbi;
|
||||
#endif
|
||||
uint64_t loop_cost;
|
||||
void (*func)(void *);
|
||||
void *ctxt;
|
||||
size_t count;
|
||||
};
|
||||
|
||||
static void
|
||||
_dispatch_benchmark_init(void *context)
|
||||
{
|
||||
struct __dispatch_benchmark_data_s *bdata = context;
|
||||
// try and simulate performance of real benchmark as much as possible
|
||||
// keep 'f', 'c' and 'cnt' in registers
|
||||
register void (*f)(void *) = bdata->func;
|
||||
register void *c = bdata->ctxt;
|
||||
register size_t cnt = bdata->count;
|
||||
size_t i = 0;
|
||||
uint64_t start, delta;
|
||||
#if DISPATCH_SIZEOF_PTR == 8 && !defined(_WIN32)
|
||||
__uint128_t lcost;
|
||||
#else
|
||||
long double lcost;
|
||||
#endif
|
||||
#if HAVE_MACH_ABSOLUTE_TIME
|
||||
kern_return_t kr;
|
||||
|
||||
kr = mach_timebase_info(&bdata->tbi);
|
||||
dispatch_assert_zero(kr);
|
||||
#endif
|
||||
|
||||
start = _dispatch_uptime();
|
||||
do {
|
||||
i++;
|
||||
f(c);
|
||||
} while (i < cnt);
|
||||
delta = _dispatch_uptime() - start;
|
||||
|
||||
lcost = delta;
|
||||
#if HAVE_MACH_ABSOLUTE_TIME
|
||||
lcost *= bdata->tbi.numer;
|
||||
lcost /= bdata->tbi.denom;
|
||||
#endif
|
||||
lcost /= cnt;
|
||||
|
||||
bdata->loop_cost = lcost > UINT64_MAX ? UINT64_MAX : (uint64_t)lcost;
|
||||
}
|
||||
|
||||
#ifdef __BLOCKS__
|
||||
uint64_t
|
||||
dispatch_benchmark(size_t count, void (^block)(void))
|
||||
{
|
||||
return dispatch_benchmark_f(count, block, _dispatch_Block_invoke(block));
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
_dispatch_benchmark_dummy_function(void *ctxt DISPATCH_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
uint64_t
|
||||
dispatch_benchmark_f(size_t count, register void *ctxt,
|
||||
register void (*func)(void *))
|
||||
{
|
||||
static struct __dispatch_benchmark_data_s bdata = {
|
||||
.func = _dispatch_benchmark_dummy_function,
|
||||
.count = 10000000ul, // ten million
|
||||
};
|
||||
static dispatch_once_t pred;
|
||||
uint64_t ns, start, delta;
|
||||
#if DISPATCH_SIZEOF_PTR == 8 && !defined(_WIN32)
|
||||
__uint128_t conversion, big_denom;
|
||||
#else
|
||||
long double conversion, big_denom;
|
||||
#endif
|
||||
size_t i = 0;
|
||||
|
||||
dispatch_once_f(&pred, &bdata, _dispatch_benchmark_init);
|
||||
|
||||
if (unlikely(count == 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
start = _dispatch_uptime();
|
||||
do {
|
||||
i++;
|
||||
func(ctxt);
|
||||
} while (i < count);
|
||||
delta = _dispatch_uptime() - start;
|
||||
|
||||
conversion = delta;
|
||||
#if HAVE_MACH_ABSOLUTE_TIME
|
||||
conversion *= bdata.tbi.numer;
|
||||
big_denom = bdata.tbi.denom;
|
||||
#else
|
||||
big_denom = delta;
|
||||
#endif
|
||||
big_denom *= count;
|
||||
conversion /= big_denom;
|
||||
ns = conversion > UINT64_MAX ? UINT64_MAX : (uint64_t)conversion;
|
||||
|
||||
return ns - bdata.loop_cost;
|
||||
}
|
||||
126
Telegram/ThirdParty/dispatch/src/block.cpp
vendored
Normal file
126
Telegram/ThirdParty/dispatch/src/block.cpp
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (c) 2015 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#ifdef __BLOCKS__
|
||||
|
||||
#if __cplusplus < 201103L
|
||||
#error Must build with C++11 or later
|
||||
#endif
|
||||
|
||||
#if __has_feature(cxx_exceptions)
|
||||
#error Must build without C++ exceptions
|
||||
#endif
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
// NOTE: this file must not contain any atomic operations
|
||||
|
||||
#if DISPATCH_DEBUG && DISPATCH_BLOCK_PRIVATE_DATA_DEBUG
|
||||
#define _dispatch_block_private_data_debug(msg, ...) \
|
||||
_dispatch_debug("block_private[%p]: " msg, (this), ##__VA_ARGS__)
|
||||
#else
|
||||
#define _dispatch_block_private_data_debug(msg, ...)
|
||||
#endif
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark _dispatch_block_create
|
||||
|
||||
// rdar://20766742 C++ helpers to enable block capture of vouchers and groups
|
||||
|
||||
struct dispatch_block_private_data_s {
|
||||
DISPATCH_BLOCK_PRIVATE_DATA_HEADER();
|
||||
static void* operator new(size_t) = delete;
|
||||
static void* operator new [] (size_t) = delete;
|
||||
explicit inline DISPATCH_ALWAYS_INLINE dispatch_block_private_data_s(
|
||||
dispatch_block_flags_t flags, voucher_t voucher,
|
||||
pthread_priority_t priority, dispatch_block_t block) noexcept :
|
||||
dbpd_magic(), dbpd_flags(flags), dbpd_atomic_flags(),
|
||||
dbpd_performed(), dbpd_priority(priority), dbpd_voucher(voucher),
|
||||
dbpd_block(block), dbpd_group(), dbpd_queue(), dbpd_thread()
|
||||
{
|
||||
// stack structure constructor, no releases on destruction
|
||||
_dispatch_block_private_data_debug("create, block: %p", dbpd_block);
|
||||
}
|
||||
inline DISPATCH_ALWAYS_INLINE dispatch_block_private_data_s(
|
||||
dispatch_block_private_data_s const &o) noexcept :
|
||||
dbpd_magic(DISPATCH_BLOCK_PRIVATE_DATA_MAGIC),
|
||||
dbpd_flags(o.dbpd_flags), dbpd_atomic_flags(), dbpd_performed(),
|
||||
dbpd_priority(o.dbpd_priority), dbpd_voucher(o.dbpd_voucher),
|
||||
dbpd_block(), dbpd_group(), dbpd_queue(), dbpd_thread()
|
||||
{
|
||||
// copy constructor, create copy with retained references
|
||||
if (dbpd_voucher && dbpd_voucher != DISPATCH_NO_VOUCHER) {
|
||||
voucher_retain(dbpd_voucher);
|
||||
}
|
||||
if (o.dbpd_block) {
|
||||
dbpd_block = reinterpret_cast<dispatch_block_t>(
|
||||
_dispatch_Block_copy(o.dbpd_block));
|
||||
}
|
||||
_dispatch_block_private_data_debug("copy from %p, block: %p from %p",
|
||||
&o, dbpd_block, o.dbpd_block);
|
||||
if (!o.dbpd_magic) return; // No group in initial copy of stack object
|
||||
dbpd_group = _dispatch_group_create_and_enter();
|
||||
}
|
||||
inline DISPATCH_ALWAYS_INLINE ~dispatch_block_private_data_s() noexcept
|
||||
{
|
||||
_dispatch_block_private_data_debug("destroy%s, block: %p",
|
||||
dbpd_magic ? "" : " (stack)", dbpd_block);
|
||||
|
||||
#if DISPATCH_INTROSPECTION
|
||||
void *db = (char *) this - sizeof(struct Block_layout);
|
||||
_dispatch_ktrace1(DISPATCH_QOS_TRACE_private_block_dispose, db);
|
||||
#endif /* DISPATCH_INTROSPECTION */
|
||||
|
||||
if (dbpd_magic != DISPATCH_BLOCK_PRIVATE_DATA_MAGIC) return;
|
||||
if (dbpd_group) {
|
||||
if (!dbpd_performed) dispatch_group_leave(dbpd_group);
|
||||
_os_object_release(dbpd_group->_as_os_obj);
|
||||
}
|
||||
if (dbpd_queue) {
|
||||
_os_object_release_internal_n(dbpd_queue->_as_os_obj, 2);
|
||||
}
|
||||
if (dbpd_block) Block_release(dbpd_block);
|
||||
if (dbpd_voucher && dbpd_voucher != DISPATCH_NO_VOUCHER) {
|
||||
voucher_release(dbpd_voucher);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
dispatch_block_t
|
||||
_dispatch_block_create(dispatch_block_flags_t flags, voucher_t voucher,
|
||||
pthread_priority_t pri, dispatch_block_t block)
|
||||
{
|
||||
struct dispatch_block_private_data_s dbpds(flags, voucher, pri, block);
|
||||
return reinterpret_cast<dispatch_block_t>(_dispatch_Block_copy(^{
|
||||
// Capture stack object: invokes copy constructor (17094902)
|
||||
(void)dbpds;
|
||||
_dispatch_block_invoke_direct(&dbpds);
|
||||
}));
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
// The compiler hides the name of the function it generates, and changes it if
|
||||
// we try to reference it directly, but the linker still sees it.
|
||||
extern void DISPATCH_BLOCK_SPECIAL_INVOKE(void *)
|
||||
__asm__(OS_STRINGIFY(__USER_LABEL_PREFIX__) "___dispatch_block_create_block_invoke");
|
||||
void (*const _dispatch_block_special_invoke)(void*) = DISPATCH_BLOCK_SPECIAL_INVOKE;
|
||||
}
|
||||
|
||||
#endif // __BLOCKS__
|
||||
740
Telegram/ThirdParty/dispatch/src/data.c
vendored
Normal file
740
Telegram/ThirdParty/dispatch/src/data.c
vendored
Normal file
@@ -0,0 +1,740 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2013 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
/*
|
||||
* Dispatch data objects are dispatch objects with standard retain/release
|
||||
* memory management. A dispatch data object either points to a number of other
|
||||
* dispatch data objects or is a leaf data object.
|
||||
* A composite data object specifies the total size of data it represents
|
||||
* and list of constituent records.
|
||||
*
|
||||
*******************************************************************************
|
||||
*
|
||||
* CURRENT IMPLEMENTATION DETAILS
|
||||
*
|
||||
* There are actually 3 kinds of composite objects
|
||||
* - trivial subranges
|
||||
* - unflattened composite data objects
|
||||
* - flattened composite data objects
|
||||
*
|
||||
* LEAVES (num_records == 0, destructor != nil)
|
||||
*
|
||||
* Those objects have a pointer to represented memory in `buf`.
|
||||
*
|
||||
* UNFLATTENED (num_records > 1, buf == nil, destructor == nil)
|
||||
*
|
||||
* This is the generic case of a composite object.
|
||||
*
|
||||
* FLATTENED (num_records > 1, buf != nil, destructor == nil)
|
||||
*
|
||||
* Those objects are non trivial composite objects whose `buf` pointer
|
||||
* is a contiguous representation (copied) of the memory it represents.
|
||||
*
|
||||
* Such objects are created when used as an NSData and -bytes is called and
|
||||
* where the dispatch data object is an unflattened composite object.
|
||||
* The underlying implementation is dispatch_data_get_flattened_bytes_4libxpc.
|
||||
*
|
||||
* TRIVIAL SUBRANGES (num_records == 1, buf == nil, destructor == nil)
|
||||
*
|
||||
* Those objects point to a single leaf, never to flattened objects.
|
||||
*
|
||||
*******************************************************************************
|
||||
*
|
||||
* Non trivial invariants:
|
||||
*
|
||||
* It is forbidden to point into a composite data object and ignore entire
|
||||
* records from it. (for example by having `from` longer than the first
|
||||
* record length).
|
||||
*
|
||||
* dispatch_data_t's are either leaves, or composite objects pointing to
|
||||
* leaves. Depth is never greater than 1.
|
||||
*
|
||||
*******************************************************************************
|
||||
*
|
||||
* There are 4 dispatch_data_t constructors who may create non leaf objects,
|
||||
* and ensure proper invariants.
|
||||
*
|
||||
* dispatch_data_copy_region()
|
||||
* This function first sees through trivial subranges, and may in turn
|
||||
* generate new trivial subranges.
|
||||
*
|
||||
* dispatch_data_create_map()
|
||||
* This function either returns existing data objects, or a leaf.
|
||||
*
|
||||
* dispatch_data_create_subrange()
|
||||
* This function treats flattened objects like unflattened ones,
|
||||
* and recurses into trivial subranges, it can create trivial subranges.
|
||||
*
|
||||
* dispatch_data_create_concat()
|
||||
* This function unwraps the top-level composite objects, trivial or not,
|
||||
* and else concatenates the two arguments range lists, hence always creating
|
||||
* unflattened objects, unless one of the arguments was empty.
|
||||
*
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
||||
#if DISPATCH_DATA_IS_BRIDGED_TO_NSDATA
|
||||
#define _dispatch_data_retain(x) _dispatch_objc_retain(x)
|
||||
#define _dispatch_data_release(x) _dispatch_objc_release(x)
|
||||
#else
|
||||
#define _dispatch_data_retain(x) dispatch_retain(x)
|
||||
#define _dispatch_data_release(x) dispatch_release(x)
|
||||
#endif
|
||||
|
||||
DISPATCH_ALWAYS_INLINE
|
||||
static inline dispatch_data_t
|
||||
_dispatch_data_alloc(size_t n, size_t extra)
|
||||
{
|
||||
dispatch_data_t data;
|
||||
size_t size;
|
||||
size_t base_size;
|
||||
|
||||
if (os_add_overflow(sizeof(struct dispatch_data_s), extra, &base_size)) {
|
||||
return DISPATCH_OUT_OF_MEMORY;
|
||||
}
|
||||
if (os_mul_and_add_overflow(n, sizeof(range_record), base_size, &size)) {
|
||||
return DISPATCH_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
data = _dispatch_object_alloc(DISPATCH_DATA_CLASS, size);
|
||||
data->num_records = n;
|
||||
#if !DISPATCH_DATA_IS_BRIDGED_TO_NSDATA
|
||||
data->do_targetq = _dispatch_get_default_queue(false);
|
||||
data->do_next = DISPATCH_OBJECT_LISTLESS;
|
||||
#endif
|
||||
return data;
|
||||
}
|
||||
|
||||
static void
|
||||
_dispatch_data_destroy_buffer(const void* buffer, size_t size,
|
||||
dispatch_queue_t queue, dispatch_block_t destructor)
|
||||
{
|
||||
if (destructor == DISPATCH_DATA_DESTRUCTOR_FREE) {
|
||||
free((void*)buffer);
|
||||
} else if (destructor == DISPATCH_DATA_DESTRUCTOR_NONE) {
|
||||
// do nothing
|
||||
#if HAVE_MACH
|
||||
} else if (destructor == DISPATCH_DATA_DESTRUCTOR_VM_DEALLOCATE) {
|
||||
mach_vm_size_t vm_size = size;
|
||||
mach_vm_address_t vm_addr = (uintptr_t)buffer;
|
||||
mach_vm_deallocate(mach_task_self(), vm_addr, vm_size);
|
||||
#else
|
||||
(void)size;
|
||||
#endif
|
||||
} else {
|
||||
if (!queue) {
|
||||
queue = _dispatch_get_default_queue(false);
|
||||
}
|
||||
dispatch_async_f(queue, destructor, _dispatch_call_block_and_release);
|
||||
}
|
||||
}
|
||||
|
||||
DISPATCH_ALWAYS_INLINE
|
||||
static inline void
|
||||
_dispatch_data_init(dispatch_data_t data, const void *buffer, size_t size,
|
||||
dispatch_queue_t queue, dispatch_block_t destructor)
|
||||
{
|
||||
data->buf = buffer;
|
||||
data->size = size;
|
||||
data->destructor = destructor;
|
||||
if (queue) {
|
||||
_dispatch_retain(queue);
|
||||
data->do_targetq = queue;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_dispatch_data_init_with_bytes(dispatch_data_t data, const void *buffer,
|
||||
size_t size, dispatch_block_t destructor)
|
||||
{
|
||||
if (!buffer || !size) {
|
||||
if (destructor) {
|
||||
_dispatch_data_destroy_buffer(buffer, size, NULL,
|
||||
_dispatch_Block_copy(destructor));
|
||||
}
|
||||
buffer = NULL;
|
||||
size = 0;
|
||||
destructor = DISPATCH_DATA_DESTRUCTOR_NONE;
|
||||
}
|
||||
_dispatch_data_init(data, buffer, size, NULL, destructor);
|
||||
}
|
||||
|
||||
dispatch_data_t
|
||||
dispatch_data_create(const void* buffer, size_t size, dispatch_queue_t queue,
|
||||
dispatch_block_t destructor)
|
||||
{
|
||||
dispatch_data_t data;
|
||||
void *data_buf = NULL;
|
||||
if (!buffer || !size) {
|
||||
// Empty data requested so return the singleton empty object. Call
|
||||
// destructor immediately in this case to ensure any unused associated
|
||||
// storage is released.
|
||||
if (destructor) {
|
||||
_dispatch_data_destroy_buffer(buffer, size, queue,
|
||||
_dispatch_Block_copy(destructor));
|
||||
}
|
||||
return dispatch_data_empty;
|
||||
}
|
||||
if (destructor == DISPATCH_DATA_DESTRUCTOR_DEFAULT) {
|
||||
// The default destructor was provided, indicating the data should be
|
||||
// copied.
|
||||
data_buf = malloc(size);
|
||||
if (unlikely(!data_buf)) {
|
||||
return DISPATCH_OUT_OF_MEMORY;
|
||||
}
|
||||
buffer = memcpy(data_buf, buffer, size);
|
||||
data = _dispatch_data_alloc(0, 0);
|
||||
destructor = DISPATCH_DATA_DESTRUCTOR_FREE;
|
||||
} else if (destructor == DISPATCH_DATA_DESTRUCTOR_INLINE) {
|
||||
data = _dispatch_data_alloc(0, size);
|
||||
buffer = memcpy((void*)data + sizeof(struct dispatch_data_s), buffer,
|
||||
size);
|
||||
destructor = DISPATCH_DATA_DESTRUCTOR_NONE;
|
||||
} else {
|
||||
data = _dispatch_data_alloc(0, 0);
|
||||
destructor = _dispatch_Block_copy(destructor);
|
||||
}
|
||||
_dispatch_data_init(data, buffer, size, queue, destructor);
|
||||
return data;
|
||||
}
|
||||
|
||||
dispatch_data_t
|
||||
dispatch_data_create_f(const void *buffer, size_t size, dispatch_queue_t queue,
|
||||
dispatch_function_t destructor_function)
|
||||
{
|
||||
dispatch_block_t destructor = (dispatch_block_t)destructor_function;
|
||||
if (destructor != DISPATCH_DATA_DESTRUCTOR_DEFAULT &&
|
||||
destructor != DISPATCH_DATA_DESTRUCTOR_FREE &&
|
||||
destructor != DISPATCH_DATA_DESTRUCTOR_NONE &&
|
||||
#if HAVE_MACH
|
||||
destructor != DISPATCH_DATA_DESTRUCTOR_VM_DEALLOCATE &&
|
||||
#endif
|
||||
destructor != DISPATCH_DATA_DESTRUCTOR_INLINE) {
|
||||
destructor = ^{ destructor_function((void*)buffer); };
|
||||
}
|
||||
return dispatch_data_create(buffer, size, queue, destructor);
|
||||
}
|
||||
|
||||
dispatch_data_t
|
||||
dispatch_data_create_alloc(size_t size, void** buffer_ptr)
|
||||
{
|
||||
dispatch_data_t data = dispatch_data_empty;
|
||||
void *buffer = NULL;
|
||||
|
||||
if (unlikely(!size)) {
|
||||
goto out;
|
||||
}
|
||||
data = _dispatch_data_alloc(0, size);
|
||||
buffer = (void*)data + sizeof(struct dispatch_data_s);
|
||||
_dispatch_data_init(data, buffer, size, NULL,
|
||||
DISPATCH_DATA_DESTRUCTOR_NONE);
|
||||
out:
|
||||
if (buffer_ptr) {
|
||||
*buffer_ptr = buffer;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
void
|
||||
_dispatch_data_dispose(dispatch_data_t dd, DISPATCH_UNUSED bool *allow_free)
|
||||
{
|
||||
if (_dispatch_data_leaf(dd)) {
|
||||
_dispatch_data_destroy_buffer(dd->buf, dd->size, dd->do_targetq,
|
||||
dd->destructor);
|
||||
} else {
|
||||
size_t i;
|
||||
for (i = 0; i < _dispatch_data_num_records(dd); ++i) {
|
||||
_dispatch_data_release(dd->records[i].data_object);
|
||||
}
|
||||
free((void *)dd->buf);
|
||||
}
|
||||
}
|
||||
|
||||
#if DISPATCH_DATA_IS_BRIDGED_TO_NSDATA
|
||||
void
|
||||
_dispatch_data_set_target_queue(dispatch_data_t dd, dispatch_queue_t tq)
|
||||
{
|
||||
if (tq == DISPATCH_TARGET_QUEUE_DEFAULT) {
|
||||
tq = _dispatch_get_default_queue(false);
|
||||
}
|
||||
_dispatch_object_set_target_queue_inline(dd, tq);
|
||||
}
|
||||
#endif // DISPATCH_DATA_IS_BRIDGED_TO_NSDATA
|
||||
|
||||
size_t
|
||||
_dispatch_data_debug(dispatch_data_t dd, char* buf, size_t bufsiz)
|
||||
{
|
||||
size_t offset = 0;
|
||||
offset += dsnprintf(&buf[offset], bufsiz - offset, "data[%p] = { ", dd);
|
||||
if (_dispatch_data_leaf(dd)) {
|
||||
offset += dsnprintf(&buf[offset], bufsiz - offset,
|
||||
"leaf, size = %zd, buf = %p ", dd->size, dd->buf);
|
||||
} else {
|
||||
offset += dsnprintf(&buf[offset], bufsiz - offset,
|
||||
"composite, size = %zd, num_records = %zd ", dd->size,
|
||||
_dispatch_data_num_records(dd));
|
||||
if (dd->buf) {
|
||||
offset += dsnprintf(&buf[offset], bufsiz - offset,
|
||||
", flatbuf = %p ", dd->buf);
|
||||
}
|
||||
size_t i;
|
||||
for (i = 0; i < _dispatch_data_num_records(dd); ++i) {
|
||||
range_record r = dd->records[i];
|
||||
offset += dsnprintf(&buf[offset], bufsiz - offset, "record[%zd] = "
|
||||
"{ from = %zd, length = %zd, data_object = %p }, ", i,
|
||||
r.from, r.length, r.data_object);
|
||||
}
|
||||
}
|
||||
offset += dsnprintf(&buf[offset], bufsiz - offset, "}");
|
||||
return offset;
|
||||
}
|
||||
|
||||
size_t
|
||||
dispatch_data_get_size(dispatch_data_t dd)
|
||||
{
|
||||
return dd->size;
|
||||
}
|
||||
|
||||
dispatch_data_t
|
||||
dispatch_data_create_concat(dispatch_data_t dd1, dispatch_data_t dd2)
|
||||
{
|
||||
dispatch_data_t data;
|
||||
size_t n;
|
||||
|
||||
if (!dd1->size) {
|
||||
_dispatch_data_retain(dd2);
|
||||
return dd2;
|
||||
}
|
||||
if (!dd2->size) {
|
||||
_dispatch_data_retain(dd1);
|
||||
return dd1;
|
||||
}
|
||||
|
||||
if (os_add_overflow(_dispatch_data_num_records(dd1),
|
||||
_dispatch_data_num_records(dd2), &n)) {
|
||||
return DISPATCH_OUT_OF_MEMORY;
|
||||
}
|
||||
data = _dispatch_data_alloc(n, 0);
|
||||
data->size = dd1->size + dd2->size;
|
||||
// Copy the constituent records into the newly created data object
|
||||
// Reference leaf objects as sub-objects
|
||||
if (_dispatch_data_leaf(dd1)) {
|
||||
data->records[0].from = 0;
|
||||
data->records[0].length = dd1->size;
|
||||
data->records[0].data_object = dd1;
|
||||
} else {
|
||||
memcpy(data->records, dd1->records, _dispatch_data_num_records(dd1) *
|
||||
sizeof(range_record));
|
||||
}
|
||||
if (_dispatch_data_leaf(dd2)) {
|
||||
data->records[_dispatch_data_num_records(dd1)].from = 0;
|
||||
data->records[_dispatch_data_num_records(dd1)].length = dd2->size;
|
||||
data->records[_dispatch_data_num_records(dd1)].data_object = dd2;
|
||||
} else {
|
||||
memcpy(data->records + _dispatch_data_num_records(dd1), dd2->records,
|
||||
_dispatch_data_num_records(dd2) * sizeof(range_record));
|
||||
}
|
||||
size_t i;
|
||||
for (i = 0; i < _dispatch_data_num_records(data); ++i) {
|
||||
_dispatch_data_retain(data->records[i].data_object);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
dispatch_data_t
|
||||
dispatch_data_create_subrange(dispatch_data_t dd, size_t offset,
|
||||
size_t length)
|
||||
{
|
||||
dispatch_data_t data;
|
||||
|
||||
if (offset >= dd->size || !length) {
|
||||
return dispatch_data_empty;
|
||||
} else if (length > dd->size - offset) {
|
||||
length = dd->size - offset;
|
||||
} else if (length == dd->size) {
|
||||
_dispatch_data_retain(dd);
|
||||
return dd;
|
||||
}
|
||||
/*
|
||||
* we must only optimize leaves and not flattened objects
|
||||
* because lots of users want to keep the end of a buffer and release
|
||||
* as much memory as they can from the beginning of it
|
||||
*
|
||||
* Using the flatbuf here would be very wrong with respect to that goal
|
||||
*/
|
||||
if (_dispatch_data_leaf(dd)) {
|
||||
data = _dispatch_data_alloc(1, 0);
|
||||
data->size = length;
|
||||
data->records[0].from = offset;
|
||||
data->records[0].length = length;
|
||||
data->records[0].data_object = dd;
|
||||
_dispatch_data_retain(dd);
|
||||
return data;
|
||||
}
|
||||
|
||||
// Subrange of a composite dispatch data object
|
||||
const size_t dd_num_records = _dispatch_data_num_records(dd);
|
||||
bool to_the_end = (offset + length == dd->size);
|
||||
size_t i = 0;
|
||||
|
||||
// find the record containing the specified offset
|
||||
while (i < dd_num_records && offset >= dd->records[i].length) {
|
||||
offset -= dd->records[i++].length;
|
||||
}
|
||||
|
||||
// Crashing here indicates memory corruption of passed in data object
|
||||
if (unlikely(i >= dd_num_records)) {
|
||||
DISPATCH_INTERNAL_CRASH(i,
|
||||
"dispatch_data_create_subrange out of bounds");
|
||||
}
|
||||
|
||||
// if everything is from a single dispatch data object, avoid boxing it
|
||||
if (offset + length <= dd->records[i].length) {
|
||||
return dispatch_data_create_subrange(dd->records[i].data_object,
|
||||
dd->records[i].from + offset, length);
|
||||
}
|
||||
|
||||
// find the record containing the end of the current range
|
||||
// and optimize the case when you just remove bytes at the origin
|
||||
size_t count, last_length = 0;
|
||||
|
||||
if (to_the_end) {
|
||||
count = dd_num_records - i;
|
||||
} else {
|
||||
last_length = length - (dd->records[i].length - offset);
|
||||
count = 1;
|
||||
|
||||
while (i + count < dd_num_records) {
|
||||
size_t record_length = dd->records[i + count++].length;
|
||||
|
||||
if (last_length <= record_length) {
|
||||
break;
|
||||
}
|
||||
last_length -= record_length;
|
||||
|
||||
// Crashing here indicates memory corruption of passed in data object
|
||||
if (unlikely(i + count >= dd_num_records)) {
|
||||
DISPATCH_INTERNAL_CRASH(i + count,
|
||||
"dispatch_data_create_subrange out of bounds");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data = _dispatch_data_alloc(count, 0);
|
||||
data->size = length;
|
||||
memcpy(data->records, dd->records + i, count * sizeof(range_record));
|
||||
|
||||
if (offset) {
|
||||
data->records[0].from += offset;
|
||||
data->records[0].length -= offset;
|
||||
}
|
||||
if (!to_the_end) {
|
||||
data->records[count - 1].length = last_length;
|
||||
}
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
_dispatch_data_retain(data->records[i].data_object);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
static void*
|
||||
_dispatch_data_flatten(dispatch_data_t dd)
|
||||
{
|
||||
void *buffer = malloc(dd->size);
|
||||
|
||||
// Composite data object, copy the represented buffers
|
||||
if (buffer) {
|
||||
dispatch_data_apply(dd, ^(dispatch_data_t region DISPATCH_UNUSED,
|
||||
size_t off, const void* buf, size_t len) {
|
||||
memcpy(buffer + off, buf, len);
|
||||
return (bool)true;
|
||||
});
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
// When mapping a leaf object or a subrange of a leaf object, return a direct
|
||||
// pointer to the represented buffer. For all other data objects, copy the
|
||||
// represented buffers into a contiguous area. In the future it might
|
||||
// be possible to relocate the buffers instead (if not marked as locked).
|
||||
dispatch_data_t
|
||||
dispatch_data_create_map(dispatch_data_t dd, const void **buffer_ptr,
|
||||
size_t *size_ptr)
|
||||
{
|
||||
dispatch_data_t data = NULL;
|
||||
const void *buffer = NULL;
|
||||
size_t size = dd->size;
|
||||
|
||||
if (!size) {
|
||||
data = dispatch_data_empty;
|
||||
goto out;
|
||||
}
|
||||
|
||||
buffer = _dispatch_data_map_direct(dd, 0, NULL, NULL);
|
||||
if (buffer) {
|
||||
_dispatch_data_retain(dd);
|
||||
data = dd;
|
||||
goto out;
|
||||
}
|
||||
|
||||
buffer = _dispatch_data_flatten(dd);
|
||||
if (likely(buffer)) {
|
||||
data = dispatch_data_create(buffer, size, NULL,
|
||||
DISPATCH_DATA_DESTRUCTOR_FREE);
|
||||
} else {
|
||||
size = 0;
|
||||
}
|
||||
|
||||
out:
|
||||
if (buffer_ptr) {
|
||||
*buffer_ptr = buffer;
|
||||
}
|
||||
if (size_ptr) {
|
||||
*size_ptr = size;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
const void *
|
||||
dispatch_data_get_flattened_bytes_4libxpc(dispatch_data_t dd)
|
||||
{
|
||||
const void *buffer;
|
||||
size_t offset = 0;
|
||||
|
||||
if (unlikely(!dd->size)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buffer = _dispatch_data_map_direct(dd, 0, &dd, &offset);
|
||||
if (buffer) {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void *flatbuf = _dispatch_data_flatten(dd);
|
||||
if (likely(flatbuf)) {
|
||||
// we need a release so that readers see the content of the buffer
|
||||
if (unlikely(!os_atomic_cmpxchgv2o(dd, buf, NULL, flatbuf,
|
||||
&buffer, release))) {
|
||||
free(flatbuf);
|
||||
} else {
|
||||
buffer = flatbuf;
|
||||
}
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return buffer + offset;
|
||||
}
|
||||
|
||||
#if DISPATCH_USE_CLIENT_CALLOUT
|
||||
DISPATCH_NOINLINE
|
||||
#else
|
||||
DISPATCH_ALWAYS_INLINE
|
||||
#endif
|
||||
static bool
|
||||
_dispatch_data_apply_client_callout(void *ctxt, dispatch_data_t region, size_t offset,
|
||||
const void *buffer, size_t size, dispatch_data_applier_function_t f)
|
||||
{
|
||||
return f(ctxt, region, offset, buffer, size);
|
||||
}
|
||||
|
||||
|
||||
static bool
|
||||
_dispatch_data_apply(dispatch_data_t dd, size_t offset, size_t from,
|
||||
size_t size, void *ctxt, dispatch_data_applier_function_t applier)
|
||||
{
|
||||
bool result = true;
|
||||
const void *buffer;
|
||||
|
||||
buffer = _dispatch_data_map_direct(dd, 0, NULL, NULL);
|
||||
if (buffer) {
|
||||
return _dispatch_data_apply_client_callout(ctxt, dd,
|
||||
offset, buffer + from, size, applier);
|
||||
}
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < _dispatch_data_num_records(dd) && result; ++i) {
|
||||
result = _dispatch_data_apply(dd->records[i].data_object,
|
||||
offset, dd->records[i].from, dd->records[i].length, ctxt,
|
||||
applier);
|
||||
offset += dd->records[i].length;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
dispatch_data_apply_f(dispatch_data_t dd, void *ctxt,
|
||||
dispatch_data_applier_function_t applier)
|
||||
{
|
||||
if (!dd->size) {
|
||||
return true;
|
||||
}
|
||||
return _dispatch_data_apply(dd, 0, 0, dd->size, ctxt, applier);
|
||||
}
|
||||
|
||||
bool
|
||||
dispatch_data_apply(dispatch_data_t dd, dispatch_data_applier_t applier)
|
||||
{
|
||||
if (!dd->size) {
|
||||
return true;
|
||||
}
|
||||
return _dispatch_data_apply(dd, 0, 0, dd->size, applier,
|
||||
(dispatch_data_applier_function_t)_dispatch_Block_invoke(applier));
|
||||
}
|
||||
|
||||
static dispatch_data_t
|
||||
_dispatch_data_copy_region(dispatch_data_t dd, size_t from, size_t size,
|
||||
size_t location, size_t *offset_ptr)
|
||||
{
|
||||
dispatch_data_t reusable_dd = NULL;
|
||||
size_t offset = 0;
|
||||
|
||||
if (from == 0 && size == dd->size) {
|
||||
reusable_dd = dd;
|
||||
}
|
||||
|
||||
if (_dispatch_data_map_direct(dd, from, &dd, &from)) {
|
||||
if (reusable_dd) {
|
||||
_dispatch_data_retain(reusable_dd);
|
||||
return reusable_dd;
|
||||
}
|
||||
|
||||
_dispatch_data_retain(dd);
|
||||
if (from == 0 && size == dd->size) {
|
||||
return dd;
|
||||
}
|
||||
|
||||
dispatch_data_t data = _dispatch_data_alloc(1, 0);
|
||||
data->size = size;
|
||||
data->records[0].from = from;
|
||||
data->records[0].length = size;
|
||||
data->records[0].data_object = dd;
|
||||
return data;
|
||||
}
|
||||
|
||||
size_t i;
|
||||
for (i = 0; i < _dispatch_data_num_records(dd); ++i) {
|
||||
size_t length = dd->records[i].length;
|
||||
|
||||
if (from >= length) {
|
||||
from -= length;
|
||||
continue;
|
||||
}
|
||||
|
||||
length -= from;
|
||||
if (location >= offset + length) {
|
||||
offset += length;
|
||||
from = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
from += dd->records[i].from;
|
||||
dd = dd->records[i].data_object;
|
||||
*offset_ptr += offset;
|
||||
location -= offset;
|
||||
return _dispatch_data_copy_region(dd, from, length, location, offset_ptr);
|
||||
}
|
||||
|
||||
DISPATCH_INTERNAL_CRASH(*offset_ptr+offset,
|
||||
"dispatch_data_copy_region out of bounds");
|
||||
}
|
||||
|
||||
// Returs either a leaf object or an object composed of a single leaf object
|
||||
dispatch_data_t
|
||||
dispatch_data_copy_region(dispatch_data_t dd, size_t location,
|
||||
size_t *offset_ptr)
|
||||
{
|
||||
if (location >= dd->size) {
|
||||
*offset_ptr = dd->size;
|
||||
return dispatch_data_empty;
|
||||
}
|
||||
*offset_ptr = 0;
|
||||
return _dispatch_data_copy_region(dd, 0, dd->size, location, offset_ptr);
|
||||
}
|
||||
|
||||
#if HAVE_MACH
|
||||
|
||||
#ifndef MAP_MEM_VM_COPY
|
||||
#define MAP_MEM_VM_COPY 0x200000 // <rdar://problem/13336613>
|
||||
#endif
|
||||
|
||||
mach_port_t
|
||||
dispatch_data_make_memory_entry(dispatch_data_t dd)
|
||||
{
|
||||
mach_port_t mep = MACH_PORT_NULL;
|
||||
memory_object_size_t mos;
|
||||
mach_vm_size_t vm_size = dd->size;
|
||||
mach_vm_address_t vm_addr;
|
||||
vm_prot_t flags;
|
||||
kern_return_t kr;
|
||||
bool copy = (dd->destructor != DISPATCH_DATA_DESTRUCTOR_VM_DEALLOCATE);
|
||||
|
||||
retry:
|
||||
if (copy) {
|
||||
vm_addr = vm_page_size;
|
||||
kr = mach_vm_allocate(mach_task_self(), &vm_addr, vm_size,
|
||||
VM_FLAGS_ANYWHERE);
|
||||
if (kr) {
|
||||
if (kr != KERN_NO_SPACE) {
|
||||
(void)dispatch_assume_zero(kr);
|
||||
}
|
||||
return mep;
|
||||
}
|
||||
dispatch_data_apply(dd, ^(dispatch_data_t region DISPATCH_UNUSED,
|
||||
size_t off, const void* buf, size_t len) {
|
||||
memcpy((void*)(vm_addr + off), buf, len);
|
||||
return (bool)true;
|
||||
});
|
||||
} else {
|
||||
vm_addr = (uintptr_t)dd->buf;
|
||||
}
|
||||
flags = VM_PROT_DEFAULT|VM_PROT_IS_MASK|MAP_MEM_VM_COPY;
|
||||
mos = vm_size;
|
||||
kr = mach_make_memory_entry_64(mach_task_self(), &mos, vm_addr, flags,
|
||||
&mep, MACH_PORT_NULL);
|
||||
if (kr == KERN_INVALID_VALUE) {
|
||||
// Fallback in case MAP_MEM_VM_COPY is not supported
|
||||
flags &= ~MAP_MEM_VM_COPY;
|
||||
kr = mach_make_memory_entry_64(mach_task_self(), &mos, vm_addr, flags,
|
||||
&mep, MACH_PORT_NULL);
|
||||
}
|
||||
if (dispatch_assume_zero(kr)) {
|
||||
mep = MACH_PORT_NULL;
|
||||
} else if (mos < vm_size) {
|
||||
// Memory object was truncated, e.g. due to lack of MAP_MEM_VM_COPY
|
||||
kr = mach_port_deallocate(mach_task_self(), mep);
|
||||
(void)dispatch_assume_zero(kr);
|
||||
if (!copy) {
|
||||
copy = true;
|
||||
goto retry;
|
||||
}
|
||||
mep = MACH_PORT_NULL;
|
||||
}
|
||||
if (copy) {
|
||||
kr = mach_vm_deallocate(mach_task_self(), vm_addr, vm_size);
|
||||
(void)dispatch_assume_zero(kr);
|
||||
}
|
||||
return mep;
|
||||
}
|
||||
#endif // HAVE_MACH
|
||||
202
Telegram/ThirdParty/dispatch/src/data.m
vendored
Normal file
202
Telegram/ThirdParty/dispatch/src/data.m
vendored
Normal file
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2013 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_APACHE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
#if DISPATCH_DATA_IS_BRIDGED_TO_NSDATA
|
||||
|
||||
#if _OS_OBJECT_OBJC_ARC
|
||||
#error "Cannot build with ARC"
|
||||
#endif
|
||||
|
||||
#include <Foundation/NSString.h>
|
||||
|
||||
// NOTE: this file must not contain any atomic operations
|
||||
|
||||
@interface DISPATCH_CLASS(data) () <DISPATCH_CLASS(data)>
|
||||
@property (readonly,nonatomic) NSUInteger length;
|
||||
@property (readonly,nonatomic) const void *bytes NS_RETURNS_INNER_POINTER;
|
||||
|
||||
- (id)initWithBytes:(void *)bytes length:(NSUInteger)length copy:(BOOL)copy
|
||||
freeWhenDone:(BOOL)freeBytes bytesAreVM:(BOOL)vm;
|
||||
- (BOOL)_bytesAreVM;
|
||||
- (BOOL)_isCompact;
|
||||
@end
|
||||
|
||||
@interface DISPATCH_CLASS(data_empty) : DISPATCH_CLASS(data)
|
||||
@end
|
||||
|
||||
@implementation DISPATCH_CLASS(data)
|
||||
|
||||
+ (id)allocWithZone:(NSZone *) DISPATCH_UNUSED zone {
|
||||
return _dispatch_objc_alloc(self, sizeof(struct dispatch_data_s));
|
||||
}
|
||||
|
||||
- (id)init {
|
||||
return [self initWithBytes:NULL length:0 copy:NO freeWhenDone:NO
|
||||
bytesAreVM:NO];
|
||||
}
|
||||
|
||||
- (id)initWithBytes:(void *)bytes length:(NSUInteger)length copy:(BOOL)copy
|
||||
freeWhenDone:(BOOL)freeBytes bytesAreVM:(BOOL)vm {
|
||||
dispatch_block_t destructor;
|
||||
if (copy) {
|
||||
destructor = DISPATCH_DATA_DESTRUCTOR_DEFAULT;
|
||||
} else if (freeBytes) {
|
||||
if (vm) {
|
||||
destructor = DISPATCH_DATA_DESTRUCTOR_VM_DEALLOCATE;
|
||||
} else {
|
||||
destructor = DISPATCH_DATA_DESTRUCTOR_FREE;
|
||||
}
|
||||
} else {
|
||||
destructor = DISPATCH_DATA_DESTRUCTOR_NONE;
|
||||
}
|
||||
_dispatch_data_init_with_bytes(self, bytes, length, destructor);
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
struct dispatch_data_s *dd = (void*)self;
|
||||
_dispatch_data_dispose(self, NULL);
|
||||
dispatch_queue_t tq = dd->do_targetq;
|
||||
dispatch_function_t func = dd->finalizer;
|
||||
void *ctxt = dd->ctxt;
|
||||
[super dealloc];
|
||||
if (func && ctxt) {
|
||||
if (!tq) {
|
||||
tq = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
|
||||
}
|
||||
dispatch_async_f(tq, ctxt, func);
|
||||
}
|
||||
if (tq) {
|
||||
_os_object_release_internal((_os_object_t)tq);
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)_bytesAreVM {
|
||||
struct dispatch_data_s *dd = (void*)self;
|
||||
return dd->destructor == DISPATCH_DATA_DESTRUCTOR_VM_DEALLOCATE;
|
||||
}
|
||||
|
||||
- (void)_setContext:(void*)context {
|
||||
struct dispatch_data_s *dd = (void*)self;
|
||||
dd->ctxt = context;
|
||||
}
|
||||
|
||||
- (void*)_getContext {
|
||||
struct dispatch_data_s *dd = (void*)self;
|
||||
return dd->ctxt;
|
||||
}
|
||||
|
||||
- (void)_setFinalizer:(dispatch_function_t)finalizer {
|
||||
struct dispatch_data_s *dd = (void*)self;
|
||||
dd->finalizer = finalizer;
|
||||
}
|
||||
|
||||
- (void)_setTargetQueue:(dispatch_queue_t)queue {
|
||||
struct dispatch_data_s *dd = (void*)self;
|
||||
return _dispatch_data_set_target_queue(dd, queue);
|
||||
}
|
||||
|
||||
- (NSString *)debugDescription {
|
||||
Class nsstring = objc_lookUpClass("NSString");
|
||||
if (!nsstring) return nil;
|
||||
char buf[2048];
|
||||
_dispatch_data_debug(self, buf, sizeof(buf));
|
||||
NSString *format = [nsstring stringWithUTF8String:"<%s: %s>"];
|
||||
if (!format) return nil;
|
||||
return [nsstring stringWithFormat:format, object_getClassName(self), buf];
|
||||
}
|
||||
|
||||
- (NSUInteger)length {
|
||||
struct dispatch_data_s *dd = (void*)self;
|
||||
return dd->size;
|
||||
}
|
||||
|
||||
- (const void *)bytes {
|
||||
return dispatch_data_get_flattened_bytes_4libxpc(self);
|
||||
}
|
||||
|
||||
- (BOOL)_isCompact {
|
||||
struct dispatch_data_s *dd = (void*)self;
|
||||
return !dd->size || _dispatch_data_map_direct(dd, 0, NULL, NULL) != NULL;
|
||||
}
|
||||
|
||||
- (void)_suspend {
|
||||
}
|
||||
|
||||
- (void)_resume {
|
||||
}
|
||||
|
||||
- (void)_activate {
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation DISPATCH_CLASS(data_empty)
|
||||
|
||||
// Force non-lazy class realization rdar://10640168
|
||||
+ (void)load {
|
||||
}
|
||||
|
||||
- (id)retain {
|
||||
return (id)self;
|
||||
}
|
||||
|
||||
- (oneway void)release {
|
||||
}
|
||||
|
||||
- (id)autorelease {
|
||||
return (id)self;
|
||||
}
|
||||
|
||||
- (NSUInteger)retainCount {
|
||||
return ULONG_MAX;
|
||||
}
|
||||
|
||||
+ (id)allocWithZone:(NSZone *) DISPATCH_UNUSED zone {
|
||||
return (id)&_dispatch_data_empty;
|
||||
}
|
||||
|
||||
- (void)_setContext:(void*) DISPATCH_UNUSED context {
|
||||
}
|
||||
|
||||
- (void*)_getContext {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- (void)_setFinalizer:(dispatch_function_t) DISPATCH_UNUSED finalizer {
|
||||
}
|
||||
|
||||
- (void)_setTargetQueue:(dispatch_queue_t) DISPATCH_UNUSED queue {
|
||||
}
|
||||
|
||||
- (void)_suspend {
|
||||
}
|
||||
|
||||
- (void)_resume {
|
||||
}
|
||||
|
||||
- (void)_activate {
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif // USE_OBJC
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user