mirror of
https://github.com/ossrs/srs.git
synced 2025-02-12 11:21:52 +00:00
commit
f9114770af
317 changed files with 36115 additions and 11795 deletions
|
@ -2,13 +2,13 @@ version: 2
|
|||
jobs:
|
||||
build:
|
||||
docker:
|
||||
- image: ossrs/dev
|
||||
- image: ossrs/srs:dev
|
||||
steps:
|
||||
- checkout
|
||||
- run: cd trunk && ./configure && make
|
||||
test:
|
||||
docker:
|
||||
- image: ossrs/dev
|
||||
- image: ossrs/srs:dev
|
||||
steps:
|
||||
- checkout
|
||||
- run: cd trunk && ./configure --gcov && make && ./objs/srs_utest && bash auto/coverage.sh
|
||||
|
@ -18,4 +18,3 @@ workflows:
|
|||
jobs:
|
||||
- build
|
||||
- test
|
||||
|
||||
|
|
34
.github/ISSUE_TEMPLATE
vendored
Normal file
34
.github/ISSUE_TEMPLATE
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
---
|
||||
name: File bug
|
||||
about: File bug to improve SRS
|
||||
title: ''
|
||||
labels: ''
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**描述(Description)**
|
||||
|
||||
> 描述你遇到了什么问题(Please description your issue here)
|
||||
|
||||
1. SRS版本(Version): `xxxxxx`
|
||||
1. SRS的日志如下(Log):
|
||||
```
|
||||
xxxxxxxxxxxx
|
||||
```
|
||||
1. SRS的配置如下(Config):
|
||||
```
|
||||
xxxxxxxxxxxx
|
||||
```
|
||||
|
||||
**重现(Replay)**
|
||||
|
||||
> 重现Bug的步骤(How to replay bug?)
|
||||
|
||||
1. `xxxxxx`
|
||||
1. `xxxxxx`
|
||||
1. `xxxxxx`
|
||||
|
||||
**期望行为(Expect)**
|
||||
|
||||
> 描述你期望发生的事情(Please describe your expectation)
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -31,3 +31,5 @@
|
|||
.AppleDouble
|
||||
|
||||
.idea
|
||||
.DS_Store
|
||||
|
||||
|
|
17
AUTHORS.txt
17
AUTHORS.txt
|
@ -36,3 +36,20 @@ CONTRIBUTORS ordered by first contribution.
|
|||
* xubin<xubin@chnvideo.com>
|
||||
* intliang<yintiliang@gmail.com>
|
||||
* flowerwrong<sysuyangkang@gmail.com>
|
||||
* YLX<568414379@qq.com>
|
||||
* J<guotaojiang@qq.com>
|
||||
* Harlan<hailiang@gvrcraft.com>
|
||||
* hankun<hankun@bravovcloud.com>
|
||||
* JonathanBarratt<jonathan.barratt@gmail.com>
|
||||
* KeeganH<keeganwharris@gmail.com>
|
||||
* StevenLiu<lingjiujianke@gmail.com>
|
||||
* liuxc0116<liuxc0116@gmail.com>
|
||||
* ChengdongZhang<lmajzcd@sina.com>
|
||||
* lovacat<lovecat@china.sina.com>
|
||||
* qiang.li<qiang.li@verycdn.com.cn>
|
||||
* HungMingWu<u9089000@gmail.com>
|
||||
* Himer<xishizhaohua@qq.com>
|
||||
* xialixin<xlx0625@163.com>
|
||||
* alphonsetai<tyh_123@163.com>
|
||||
* Michael.Ma<wnpllr@gmail.com>
|
||||
* lam2003<linmin3@yy.com>
|
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2019 Winlin
|
||||
Copyright (c) 2013-2020 Winlin
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
|
|
475
README.md
475
README.md
|
@ -1,53 +1,19 @@
|
|||
# Simple-RTMP-Server
|
||||
# SRS
|
||||
|
||||
![](http://ossrs.net/gif/v1/sls.gif?site=github.com&path=/srs/srs3)
|
||||
[![](https://circleci.com/gh/ossrs/srs/tree/3.0release.svg?style=svg&circle-token=1ef1d5b5b0cde6c8c282ed856a18199f9e8f85a9)](https://circleci.com/gh/ossrs/srs/tree/3.0release)
|
||||
[![](https://codecov.io/gh/ossrs/srs/branch/3.0release/graph/badge.svg)](https://codecov.io/gh/ossrs/srs/branch/3.0release)
|
||||
[![](https://cloud.githubusercontent.com/assets/2777660/22814959/c51cbe72-ef92-11e6-81cc-32b657b285d5.png)](https://github.com/ossrs/srs/wiki/v1_CN_Contact#wechat)
|
||||
[<img width="52" alt="Skype" src="https://cloud.githubusercontent.com/assets/2777660/24329166/3821a328-1230-11e7-844a-506a5d17dd3d.png">](https://github.com/ossrs/srs/wiki/v1_EN_Contact#skype-or-gitter)
|
||||
|
||||
SRS/3.0,[OuXuli][release3],是一个简单的流媒体直播集群,简单的快乐。<br/>
|
||||
SRS, a simple joy, created on 2013.10, is a simple live streaming cluster.
|
||||
|
||||
Download binaries from github.io: [Centos6-x86_64][centos0], [more...][more0]<br/>
|
||||
Download binaries from ossrs.net: [Centos6-x86_64][centos1], [more...][more1]<br/>
|
||||
About the wiki of SRS/3.0, please read [Chinese][srs_CN] or [English][srs_EN].
|
||||
|
||||
> Remark: SRS3 hasn't been released and it's really unstable, please use stable branches such as [SRS2](https://github.com/ossrs/srs/tree/2.0release) or [SRS1](https://github.com/ossrs/srs/tree/1.0release) instead, unless you can fix bugs and debug it.
|
||||
SRS/3.0,[OuXuli][release3],是一个流媒体集群,支持RTMP/HLS/WebRTC/SRT/GB28181,高效、稳定、易用,简单而快乐。<br/>
|
||||
SRS is a RTMP/HLS/WebRTC/SRT/GB28181 streaming cluster, high efficiency, stable and simple.
|
||||
|
||||
> Remark: Although SRS is licenced under [MIT][LICENSE], but there are some depended libraries which are distributed using their own licenses, please read [License Mixing][LicenseMixing].
|
||||
|
||||
> Remark: About the milestone and product plan, please read ([CN][v1_CN_Product], [EN][v1_EN_Product]) wiki.
|
||||
|
||||
> Remark: The origin-edge cluster is released, while the origin-origin cluster is coming soon.
|
||||
|
||||
> Remark: We are working on utest now.
|
||||
|
||||
Enjoy it!
|
||||
|
||||
## Content
|
||||
|
||||
* [Usage](#usage)
|
||||
* [Wiki](#srs-30-wiki)
|
||||
* [Features](#features)
|
||||
* [v3.0 changes](#v3-changes)
|
||||
* [v2.0 changes](#v2-changes)
|
||||
* [v1.0 changes](#v1-changes)
|
||||
* [Releases](#releases)
|
||||
* [Compare](#compare)
|
||||
* [Performance](#performance)
|
||||
* [Architecture](#architecture)
|
||||
* [System Architecture](#system-architecture)
|
||||
* [Modularity Architecture](#modularity-architecture)
|
||||
* [Stream Architecture](#stream-architecture)
|
||||
* [Authors](#authors)
|
||||
* [Mirrors](#mirrors)
|
||||
* [System Requirements](#system-requirements)
|
||||
|
||||
<a name="product"></a>
|
||||
## Usage
|
||||
|
||||
### Usage
|
||||
|
||||
<strong>Step 1:</strong> Get SRS.
|
||||
**Step 1:** Get SRS.
|
||||
|
||||
```
|
||||
git clone https://github.com/ossrs/srs &&
|
||||
|
@ -56,23 +22,29 @@ cd srs/trunk
|
|||
|
||||
> Note: Repository too large? Please clone from these [mirrors](#mirrors) instead.
|
||||
|
||||
<strong>Step 2:</strong> Build SRS.
|
||||
**Step 2:** Build SRS.
|
||||
|
||||
```
|
||||
./configure && make
|
||||
```
|
||||
|
||||
> Remark: Recommend Centos6 64bits, for other OS recommend [docker][docker], please read wiki([CN][v3_CN_Build],[EN][v3_EN_Build]).
|
||||
> Remark: Recommend Centos6 64bits, please read wiki([CN][v3_CN_Build],[EN][v3_EN_Build]).
|
||||
|
||||
> Note: If you have multiple cores such as 4 cores CPU, please use `./configure --jobs=4 && make --jobs=4` to speeed up the build.
|
||||
> Note: You can also build SRS in docker, please read [docker][docker-dev].
|
||||
|
||||
<strong>Step 3:</strong> Run SRS
|
||||
**Step 3:** Run SRS
|
||||
|
||||
```
|
||||
./objs/srs -c conf/srs.conf
|
||||
```
|
||||
|
||||
<strong>From here, </strong> strongly recommend to try other main use-scenarios:
|
||||
**Whatever**, you can also directly run SRS in [docker][docker-srs3]:
|
||||
|
||||
```
|
||||
docker run -p 1935:1935 -p 1985:1985 -p 8080:8080 ossrs/srs:3
|
||||
```
|
||||
|
||||
**From here,** strongly recommend to read bellow wikis:
|
||||
|
||||
* Usage: How to delivery RTMP?([CN][v1_CN_SampleRTMP], [EN][v1_EN_SampleRTMP])
|
||||
* Usage: How to delivery RTMP Edge Cluster?([CN][v3_CN_SampleRTMPCluster], [EN][v3_EN_SampleRTMPCluster])
|
||||
|
@ -84,21 +56,29 @@ cd srs/trunk
|
|||
* Usage: How to transode RTMP stream by FFMPEG?([CN][v2_CN_SampleFFMPEG], [EN][v2_EN_SampleFFMPEG])
|
||||
* Usage: How to forward stream to other servers?([CN][v3_CN_SampleForward], [EN][v3_EN_SampleForward])
|
||||
* Usage: How to deploy in low lantency mode?([CN][v3_CN_SampleRealtime], [EN][v3_EN_SampleRealtime])
|
||||
* Usage: How to deploy on ARM or MIPS?([CN][v1_CN_SampleARM], [EN][v1_EN_SampleARM])
|
||||
* Usage: How to ingest file/stream/device to RTMP?([CN][v1_CN_SampleIngest], [EN][v1_EN_SampleIngest])
|
||||
* Usage: How to delivery HLS by embeded HTTP server?([CN][v3_CN_SampleHTTP], [EN][v3_EN_SampleHTTP])
|
||||
* Usage: How to run the demostration of SRS? ([CN][v1_CN_SampleDemo], [EN][v1_EN_SampleDemo])
|
||||
* Usage: How to delivery HLS by SRS HTTP server?([CN][v3_CN_SampleHTTP], [EN][v3_EN_SampleHTTP])
|
||||
* Usage: How to publish h.264 raw stream as RTMP? ([CN][v3_CN_SrsLibrtmp2], [EN][v3_EN_SrsLibrtmp2])
|
||||
* Usage: Who are using SRS?([CN][v1_CN_Sample])
|
||||
* Usage: How to improve edge performance by multiple CPUs? ([CN][v3_CN_REUSEPORT], [EN][v3_EN_REUSEPORT])
|
||||
* Usage: Why choose SRS? About the milestone and product plan? ([CN][v1_CN_Product], [EN][v1_EN_Product])
|
||||
* Usage: How to file bug or chat with us? ([CN][v1_CN_Contact], [EN][v1_EN_Contact])
|
||||
|
||||
### SRS 3.0 wiki
|
||||
<a name="srs-30-wiki"></a>
|
||||
## Wiki
|
||||
|
||||
Please select according to languages:
|
||||
* [SRS 3.0 English][v3_EN_Home]
|
||||
* [SRS 3.0 Chinese][v3_CN_Home]
|
||||
|
||||
### Features
|
||||
* [SRS 3.0 English Wiki][v3_EN_Home]
|
||||
* [SRS 3.0 Chinese Wiki][v3_CN_Home]
|
||||
|
||||
For previous versions, please read:
|
||||
|
||||
* [SRS 2.0 English Wiki][v2_EN_Home]
|
||||
* [SRS 2.0 Chinese Wiki][v2_CN_Home]
|
||||
* [SRS 1.0 English Wiki][v1_EN_Home]
|
||||
* [SRS 1.0 Chinese Wiki][v1_CN_Home]
|
||||
|
||||
## Features
|
||||
|
||||
- [x] Using coroutine by ST, it's really simple and stupid enough.
|
||||
- [x] Support cluster which consists of origin ([CN][v1_CN_DeliveryRTMP],[EN][v1_EN_DeliveryRTMP]) and edge([CN][v3_CN_Edge], [EN][v3_EN_Edge]) server and uses RTMP as default transport protocol.
|
||||
|
@ -107,11 +87,6 @@ Please select according to languages:
|
|||
- [x] Support HLS with audio-only([CN][v3_CN_DeliveryHLS2], [EN][v3_EN_DeliveryHLS2]), which need to build the timestamp from AAC samples, so we enhanced it please read [#547][bug #547].
|
||||
- [x] Support HLS with mp3(h.264+mp3) audio codec, please read [bug #301][bug #301].
|
||||
- [x] Support remuxing RTMP to http FLV/MP3/AAC/TS live streaming, please read wiki([CN][v2_CN_DeliveryHttpStream], [EN][v2_CN_DeliveryHttpStream]).
|
||||
- [x] [Experimental] Support MPEG-DASH, the future live streaming protocol, read [#299][bug #299].
|
||||
- [x] [Experimental] Support Adobe HDS(f4m), please read wiki([CN][v2_CN_DeliveryHDS], [EN][v2_EN_DeliveryHDS]).
|
||||
- [x] [Experimental] Support pushing MPEG-TS over UDP, please read [bug #250][bug #250].
|
||||
- [x] [Experimental] Support pushing RTSP, please read [bug #133][bug #133].
|
||||
- [x] [Experimental] Support pushing FLV over HTTP POST, please read [wiki]([CN][v2_CN_Streamer2], [EN][v2_EN_Streamer2]).
|
||||
- [x] Support ingesting([CN][v1_CN_Ingest], [EN][v1_EN_Ingest]) other protocols to SRS by FFMPEG.
|
||||
- [x] Support RTMP long time(>4.6hours) publishing/playing, with the timestamp corrected.
|
||||
- [x] Support publishing h264 raw stream([CN][v3_CN_SrsLibrtmp2], [EN][v3_EN_SrsLibrtmp2]) by srs-librtmp([CN][v3_CN_SrsLibrtmp], [EN][v3_EN_SrsLibrtmp]).
|
||||
|
@ -119,12 +94,8 @@ Please select according to languages:
|
|||
- [x] Support native HTTP server([CN][v3_CN_SampleHTTP], [EN][v3_EN_SampleHTTP]) for http api and http live streaming.
|
||||
- [x] Support HTTP CORS for js in http api and http live streaming.
|
||||
- [x] Support HTTP API([CN][v3_CN_HTTPApi], [EN][v3_EN_HTTPApi]) for system management.
|
||||
- [x] Support HTTP RAW API, please read [#459][bug #459], [#470][bug #470], [#319][bug #319].
|
||||
- [x] Support HTTP callback([CN][v3_CN_HTTPCallback], [EN][v3_EN_HTTPCallback]) for authentication and integration.
|
||||
- [x] Support RTMP client library: srs-librtmp([CN][v3_CN_SrsLibrtmp], [EN][v3_EN_SrsLibrtmp])
|
||||
- [x] Support Adobe FMS/AMS token traverse([CN][v3_CN_DRM2], [EN][v3_EN_DRM2]) authentication.
|
||||
- [x] Support DVR([CN][v3_CN_DVR], [EN][v3_EN_DVR]) to record live streaming to FLV file.
|
||||
- [x] Support DVR in MP4 format, read [#738][bug #738].
|
||||
- [x] Support DVR control module like NGINX-RTMP, please read [#459][bug #459].
|
||||
- [x] Support EXEC like NGINX-RTMP, please read [bug #367][bug #367].
|
||||
- [x] Support security strategy including allow/deny publish/play IP([CN][v2_CN_Security], [EN][v2_EN_Security]).
|
||||
|
@ -132,13 +103,9 @@ Please select according to languages:
|
|||
- [x] Support gop-cache([CN][v3_CN_LowLatency2], [EN][v3_EN_LowLatency2]) for player fast startup.
|
||||
- [x] Support Vhost([CN][v1_CN_RtmpUrlVhost], [EN][v1_EN_RtmpUrlVhost]) and \_\_defaultVhost\_\_.
|
||||
- [x] Support reloading([CN][v1_CN_Reload], [EN][v1_EN_Reload]) to apply changes of config.
|
||||
- [x] Support bandwidth testing([CN][v1_CN_BandwidthTestTool], [EN][v1_EN_BandwidthTestTool]) and flash client example.
|
||||
- [x] Support listening at multiple ports.
|
||||
- [x] Support forwarding([CN][v3_CN_Forward], [EN][v3_EN_Forward]) from master to slave server.
|
||||
- [x] Support transcoding([CN][v3_CN_FFMPEG], [EN][v3_EN_FFMPEG]) live streaming by FFMPEG.
|
||||
- [x] [Experimental] Support multiple processes by [dolphin][srs-dolphin] or [oryx][oryx].
|
||||
- [x] [Experimental] Support big-data by sending messages to KAFKA, please read [#467][bug #467].
|
||||
- [x] [Experimental] Support a simple [mgmt console][console], please read [srs-ngb][srs-ngb].
|
||||
- [x] All wikis are writen in [Chinese][v3_CN_Home] and [English][v3_EN_Home].
|
||||
- [x] Enhanced json, replace NXJSON(LGPL) with json-parser(BSD), read [#904][bug #904].
|
||||
- [x] Support valgrind and latest ARM by patching ST, read [ST#1](https://github.com/ossrs/state-threads/issues/1) and [ST#2](https://github.com/ossrs/state-threads/issues/2).
|
||||
|
@ -147,23 +114,151 @@ Please select according to languages:
|
|||
- [x] Enhanced complex error code with description and stack, read [#913][bug #913].
|
||||
- [x] Enhanced RTMP url which supports vhost in stream, read [#1059][bug #1059].
|
||||
- [x] Support origin cluster, please read [#464][bug #464], [RTMP 302][bug #92].
|
||||
- [ ] Utest cover almost all kernel code.
|
||||
- [x] Support listen at IPv4 and IPv6, read [#460][bug #460].
|
||||
- [x] Support SO_REUSEPORT, to improve edge server performance, read [#775][bug #775].
|
||||
- [x] Improve test coverage for core/kernel/protocol/service.
|
||||
- [x] [Experimental] Support docker by [srs-docker](https://github.com/ossrs/srs-docker).
|
||||
- [x] [Experimental] Support DVR in MP4 format, read [#738][bug #738].
|
||||
- [x] [Experimental] Support MPEG-DASH, the future live streaming protocol, read [#299][bug #299].
|
||||
- [x] [Experimental] Support pushing MPEG-TS over UDP, please read [bug #250][bug #250].
|
||||
- [x] [Experimental] Support pushing RTSP, please read [bug #133][bug #133].
|
||||
- [x] [Experimental] Support pushing FLV over HTTP POST, please read [wiki]([CN][v2_CN_Streamer2], [EN][v2_EN_Streamer2]).
|
||||
- [x] [Experimental] Support multiple processes by [dolphin][srs-dolphin] or [oryx][oryx].
|
||||
- [x] [Experimental] Support a simple [mgmt console][console], please read [srs-ngb][srs-ngb].
|
||||
- [x] [Experimental] Support RTMP client library: srs-librtmp([CN][v3_CN_SrsLibrtmp], [EN][v3_EN_SrsLibrtmp])
|
||||
- [x] [Experimental] Support HTTP RAW API, please read [#459][bug #459], [#470][bug #470], [#319][bug #319].
|
||||
- [x] [Deprecated] Support Adobe HDS(f4m), please read wiki([CN][v2_CN_DeliveryHDS], [EN][v2_EN_DeliveryHDS]) and [#1535][bug #1535].
|
||||
- [x] [Deprecated] Support bandwidth testing([CN][v1_CN_BandwidthTestTool], [EN][v1_EN_BandwidthTestTool]), please read [#1535][bug #1535].
|
||||
- [x] [Deprecated] Support Adobe FMS/AMS token traverse([CN][v3_CN_DRM2], [EN][v3_EN_DRM2]) authentication, please read [#1535][bug #1535].
|
||||
- [ ] Enhanced forwarding with vhost and variables.
|
||||
- [ ] Support listen at IPv4 and IPv6, read [#460][bug #460].
|
||||
- [ ] Support source cleanup for idle streams.
|
||||
- [ ] Support H.265 by pushing H.265 over RTMP, deliverying in HLS, read [#465][bug #465].
|
||||
- [ ] Support HLS+, the HLS edge server, please read [#466][bug #466] and [#468][bug #468].
|
||||
- [ ] Support UDP protocol such as QUIC or KCP in cluster.
|
||||
- [ ] Support H.264+Opus codec for WebRTC.
|
||||
- [ ] Support publishing stream by WebRTC.
|
||||
- [ ] Support playing stream by WebRTC.
|
||||
|
||||
> Remark: About the milestone and product plan, please read ([CN][v1_CN_Product], [EN][v1_EN_Product]) wiki.
|
||||
|
||||
<a name="history"></a>
|
||||
<a name="change-logs"></a>
|
||||
|
||||
### V3 changes
|
||||
## V3 changes
|
||||
|
||||
* <strong>v3.0, 2020-03-18, [3.0 beta3(3.0.134)][r3.0b3] released. 122509 lines.</strong>
|
||||
* v3.0, 2020-03-12, For [#1635][bug #1635], inotify watch ConfigMap for reload. 3.0.134
|
||||
* v3.0, 2020-03-12, For [#1635][bug #1635], support auto reaload config by inotify. 3.0.129
|
||||
* v3.0, 2020-03-12, For [#1630][bug #1630], disable cache for stream changing, and drop dup header. 3.0.128
|
||||
* v3.0, 2020-03-12, For [#1594][bug #1594], detect and disable daemon for docker. 3.0.127
|
||||
* v3.0, 2020-03-12, For [#1634][bug #1634], always check status in thread loop. 3.0.126
|
||||
* v3.0, 2020-03-11, For [#1634][bug #1634], refactor output with datetime for ingest/encoder/exec. 3.0.125
|
||||
* v3.0, 2020-03-11, For [#1634][bug #1634], fix quit by accident SIGTERM while killing FFMPEG. 3.0.124
|
||||
* <strong>v3.0, 2020-03-05, [3.0 beta2(3.0.123)][r3.0b2] released. 122170 lines.</strong>
|
||||
* v3.0, 2020-02-21, For [#1598][bug #1598], support SLB health checking by TCP. 3.0.123
|
||||
* v3.0, 2020-02-21, Fix bug for librtmp client ipv4/ipv6 socket. 3.0.122
|
||||
* v3.0, 2020-02-18, For [#1579][bug #1579], support start/final wait for gracefully quit. 3.0.121
|
||||
* v3.0, 2020-02-18, For [#1579][bug #1579], support force gracefully quit. 3.0.120
|
||||
* v3.0, 2020-02-18, For [#1579][bug #1579], support gracefully quit. 3.0.119
|
||||
* v3.0, 2020-02-17, For [#1601][bug #1601], flush async on_dvr/on_hls events before stop. 3.0.118
|
||||
* <strong>v3.0, 2020-02-14, [3.0 beta1(3.0.117)][r3.0b1] released. 121964 lines.</strong>
|
||||
* v3.0, 2020-02-14, For [#1595][bug #1595], migrating streaming from ossrs.net to r.ossrs.net. 3.0.117
|
||||
* v3.0, 2020-02-05, For [#665][bug #665], fix HTTP-FLV reloading bug. 3.0.116
|
||||
* v3.0, 2020-02-05, For [#1592][bug #1592], fix terminal echo off by redirect process stdin. 3.0.115
|
||||
* v3.0, 2020-02-04, For [#1186][bug #1186], refactor security check. 3.0.114
|
||||
* v3.0, 2020-02-04, Fix [#939][bug #939], response right A/V flag in FLV header. 3.0.113
|
||||
* v3.0, 2020-02-04, For [#939][bug #939], always enable fast FLV streaming.
|
||||
* <strong>v3.0, 2020-02-02, [3.0 beta0(3.0.112)][r3.0b0] released. 121709 lines.</strong>
|
||||
* v3.0, 2020-01-29, Support isolate version file. 3.0.112
|
||||
* v3.0, 2020-01-29, Fix [#1206][bug #1206], dispose ingester while server quiting. 3.0.111
|
||||
* v3.0, 2020-01-28, Fix [#1230][bug #1230], racing condition in source fetch or create. 3.0.110
|
||||
* v3.0, 2020-01-27, Fix [#1303][bug #1303], do not dispatch previous meta when not publishing. 3.0.109
|
||||
* v3.0, 2020-01-26, Allow use libst.so for ST is MPL license.
|
||||
* v3.0, 2020-01-26, Fix [#607][bug #607], set RTMP identifying recursive depth to 3.
|
||||
* v3.0, 2020-01-25, Fix [#878][bug #878], remove deprecated #EXT-X-ALLOW-CACHE for HLS. 3.0.108
|
||||
* v3.0, 2020-01-25, Fix [#703][bug #703], drop video data util sps/pps. 3.0.107
|
||||
* v3.0, 2020-01-25, Fix [#1108][bug #1108], reap DVR tmp file when unpublish. 3.0.106
|
||||
* <strong>v3.0, 2020-01-21, [3.0 alpha9(3.0.105)][r3.0a9] released. 121577 lines.</strong>
|
||||
* v3.0, 2020-01-21, Fix [#1221][bug #1221], remove complex configure options. 3.0.104
|
||||
* v3.0, 2020-01-21, Fix [#1547][bug #1547], support crossbuild for ARM/MIPS.
|
||||
* v3.0, 2020-01-21, For [#1547][bug #1547], support setting cc/cxx/ar/ld/randlib tools. 3.0.103
|
||||
* v3.0, 2020-01-19, For [#1580][bug #1580], fix cid range problem. 3.0.102
|
||||
* v3.0, 2020-01-19, For [#1070][bug #1070], define FLV CodecID for [AV1][bug #1070] and [opus][bug #307]. 3.0.101
|
||||
* v3.0, 2020-01-16, For [#1575][bug #1575], correct RTMP redirect as tcUrl, add redirect2 as RTMP URL. 3.0.100
|
||||
* v3.0, 2020-01-15, For [#1509][bug #1509], decrease the fast vector init size from 64KB to 64B. 3.0.99
|
||||
* v3.0, 2020-01-15, For [#1509][bug #1509], release coroutine when source is idle. 3.0.98
|
||||
* <strong>v3.0, 2020-01-10, [3.0 alpha8(3.0.97)][r3.0a8] released. 121555 lines.</strong>
|
||||
* v3.0, 2020-01-09, For [#1042][bug #1042], improve test coverage for service. 3.0.97
|
||||
* v3.0, 2020-01-08, Merge [#1554][bug #1554], support logrotate copytruncate. 3.0.96
|
||||
* v3.0, 2020-01-05, Always use string instance to avoid crash risk. 3.0.95
|
||||
* v3.0, 2020-01-05, For [#460][bug #460], fix ipv6 hostport parsing bug. 3.0.94
|
||||
* v3.0, 2020-01-05, For [#460][bug #460], fix ipv6 intranet address filter bug. 3.0.93
|
||||
* v3.0, 2020-01-05, For [#1543][bug #1543], use getpeername to retrieve client ip. 3.0.92
|
||||
* v3.0, 2020-01-02, For [#1042][bug #1042], improve test coverage for config. 3.0.91
|
||||
* v3.0, 2019-12-30, Fix mp4 security issue, check buffer when required size is variable.
|
||||
* <strong>v3.0, 2019-12-29, [3.0 alpha7(3.0.90)][r3.0a7] released. 116356 lines.</strong>
|
||||
* v3.0, 2019-12-29, For [#1255][bug #1255], support vhost/domain in query string for HTTP streaming. 3.0.90
|
||||
* v3.0, 2019-12-29, For [#299][bug #299], increase dash segment size for avsync issue. 3.0.89
|
||||
* v3.0, 2019-12-27, For [#299][bug #299], fix some bugs in dash, it works now. 3.0.88
|
||||
* v3.0, 2019-12-27, For [#1544][bug #1544], fix memory leaking for complex error. 3.0.87
|
||||
* v3.0, 2019-12-27, Add links for flv.js, hls.js and dash.js.
|
||||
* v3.0, 2019-12-26, For [#1105][bug #1105], http server support mp4 range.
|
||||
* v3.0, 2019-12-26, For [#1105][bug #1105], dvr mp4 supports playing on Chrome/Safari/Firefox. 3.0.86
|
||||
* <strong>v3.0, 2019-12-26, [3.0 alpha6(3.0.85)][r3.0a6] released. 116056 lines.</strong>
|
||||
* v3.0, 2019-12-26, For [#1488][bug #1488], pass client ip to http callback. 3.0.85
|
||||
* v3.0, 2019-12-25, For [#1537][bug #1537], [#1282][bug #1282], support aarch64 for armv8. 3.0.84
|
||||
* v3.0, 2019-12-25, For [#1538][bug #1538], fresh chunk allow fmt=0 or fmt=1. 3.0.83
|
||||
* v3.0, 2019-12-25, Remove FFMPEG and NGINX, please use [srs-docker](https://github.com/ossrs/srs-docker) instead. 3.0.82
|
||||
* v3.0, 2019-12-25, For [#1537][bug #1537], remove cross-build, not used patches, directly build st.
|
||||
* v3.0, 2019-12-24, For [#1508][bug #1508], support chunk length and content in multiple parts.
|
||||
* v3.0, 2019-12-23, Merge SRS2 for running srs-librtmp on Windows. 3.0.80
|
||||
* v3.0, 2019-12-23, For [#1535][bug #1535], deprecate Adobe FMS/AMS edge token traversing([CN][v3_CN_DRM2], [EN][v3_EN_DRM2]) authentication. 3.0.79
|
||||
* v3.0, 2019-12-23, For [#1535][bug #1535], deprecate BWT(bandwidth testing)([CN][v1_CN_BandwidthTestTool], [EN][v1_EN_BandwidthTestTool]). 3.0.78
|
||||
* v3.0, 2019-12-23, For [#1535][bug #1535], deprecate Adobe HDS(f4m)([CN][v2_CN_DeliveryHDS], [EN][v2_EN_DeliveryHDS]). 3.0.77
|
||||
* v3.0, 2019-12-20, Fix [#1508][bug #1508], http-client support read chunked response. 3.0.76
|
||||
* v3.0, 2019-12-20, For [#1508][bug #1508], refactor srs_is_digital, support all zeros.
|
||||
* <strong>v3.0, 2019-12-19, [3.0 alpha5(3.0.75)][r3.0a5] released. 115362 lines.</strong>
|
||||
* v3.0, 2019-12-19, Refine the RTMP iovs cache increasing to much faster.
|
||||
* v3.0, 2019-12-19, Fix [#1524][bug #1524], memory leak for amf0 strict array. 3.0.75
|
||||
* v3.0, 2019-12-19, Fix random build failed bug for modules.
|
||||
* v3.0, 2019-12-19, Fix [#1520][bug #1520] and [#1223][bug #1223], bug for origin cluster 3+ servers. 3.0.74
|
||||
* v3.0, 2019-12-18, For [#1042][bug #1042], add test for RAW AVC protocol.
|
||||
* v3.0, 2019-12-18, Detect whether flash enabled for srs-player. 3.0.73
|
||||
* v3.0, 2019-12-17, Fix HTTP CORS bug when sending response for OPTIONS. 3.0.72
|
||||
* v3.0, 2019-12-17, Enhance HTTP response write for final_request.
|
||||
* v3.0, 2019-12-17, Refactor HTTP stream to disconnect client when unpublish.
|
||||
* v3.0, 2019-12-17, Fix HTTP-FLV and VOD-FLV conflicting bug.
|
||||
* v3.0, 2019-12-17, Refactor HttpResponseWriter.write, default to single text mode.
|
||||
* v3.0, 2019-12-16, For [#1042][bug #1042], add test for HTTP protocol.
|
||||
* <strong>v3.0, 2019-12-13, [3.0 alpha4(3.0.71)][r3.0a4] released. 112928 lines.</strong>
|
||||
* v3.0, 2019-12-12, For [#547][bug #547], [#1506][bug #1506], default hls_dts_directly to on. 3.0.71
|
||||
* v3.0, 2019-12-12, SrsPacket supports converting to message, so can be sent by one API.
|
||||
* v3.0, 2019-12-11, For [#1042][bug #1042], cover RTMP client/server protocol.
|
||||
* v3.0, 2019-12-11, Fix [#1445][bug #1445], limit the createStream recursive depth. 3.0.70
|
||||
* v3.0, 2019-12-11, For [#1042][bug #1042], cover RTMP handshake protocol.
|
||||
* v3.0, 2019-12-11, Fix [#1229][bug #1229], fix the security risk in logger. 3.0.69
|
||||
* v3.0, 2019-12-11, For [#1229][bug #1229], fix the security risk in HDS. 3.0.69
|
||||
* v3.0, 2019-12-05, Fix [#1506][bug #1506], support directly turn FLV timestamp to TS DTS. 3.0.68
|
||||
* <strong>v3.0, 2019-11-30, [3.0 alpha3(3.0.67)][r3.0a3] released. 110864 lines.</strong>
|
||||
* v3.0, 2019-12-01, Fix [#1501][bug #1501], use request coworker for origin cluster. 3.0.67
|
||||
* <strong>v3.0, 2019-11-30, [3.0 alpha2(3.0.66)][r3.0a2] released. 110831 lines.</strong>
|
||||
* v3.0, 2019-11-30, Fix [#1501][bug #1501], use request coworker for origin cluster. 3.0.66
|
||||
* v3.0, 2019-11-30, Random tid for docker. 3.0.65
|
||||
* v3.0, 2019-11-30, Refine debug info for edge. 3.0.64
|
||||
* v3.0, 2019-10-30, Cover protocol stack RTMP. 3.0.63
|
||||
* v3.0, 2019-10-23, Cover JSON codec. 3.0.62
|
||||
* v3.0, 2019-10-13, Use http://ossrs.net as homepage.
|
||||
* v3.0, 2019-10-10, Cover AMF0 codec. 3.0.61
|
||||
* <strong>v3.0, 2019-10-07, [3.0 alpha1(3.0.60)][r3.0a1] released. 107962 lines.</strong>
|
||||
* v3.0, 2019-10-06, Support log rotate by init.d command. 3.0.60
|
||||
* v3.0, 2019-10-06, We prefer ipv4, only use ipv6 if ipv4 is disabled. 3.0.59
|
||||
* v3.0, 2019-10-05, Support systemctl service for CentOS7. 3.0.58
|
||||
* v3.0, 2019-10-04, Disable SO_REUSEPORT if not supported. 3.0.57
|
||||
* <strong>v3.0, 2019-10-04, [3.0 alpha0(3.0.56)][r3.0a0] released. 107946 lines.</strong>
|
||||
* v3.0, 2019-10-04, Support go-oryx rtmplb with [proxy protocol](https://github.com/ossrs/go-oryx/wiki/RtmpProxy). 3.0.56
|
||||
* v3.0, 2019-10-03, Fix [#775][bug #775], Support SO_REUSEPORT to improve edge performance. 3.0.54
|
||||
* v3.0, 2019-10-03, For [#467][bug #467], Remove KAFKA producer. 3.0.53
|
||||
* v3.0, 2019-05-14, Covert Kernel File reader/writer. 3.0.52
|
||||
* v3.0, 2019-04-30, Refine typo in files. 3.0.51
|
||||
* v3.0, 2019-04-25, Upgrade http-parser from 2.1 to 2.9.2 and cover it. 3.0.50
|
||||
* v3.0, 2019-04-22, Refine in time unit. 3.0.49
|
||||
|
@ -208,7 +303,6 @@ Please select according to languages:
|
|||
* v3.0, 2016-12-15, fix [#717][bug #717], [#691][bug #691], http api/static/stream support cors. 3.0.9
|
||||
* v3.0, 2016-12-08, Fix [#105][bug #105], support log rotate signal SIGUSR1. 3.0.8
|
||||
* v3.0, 2016-12-07, fix typo and refine grammar. 3.0.7
|
||||
* v3.0, 2015-10-23, fix [#467][bug #467], support write log to kafka. 3.0.6
|
||||
* v3.0, 2015-10-20, fix [#502][bug #502], support snapshot with http-callback or transcoder. 3.0.5
|
||||
* v3.0, 2015-09-19, support amf0 and json to convert with each other.
|
||||
* v3.0, 2015-09-19, json objects support dumps to string.
|
||||
|
@ -219,8 +313,17 @@ Please select according to languages:
|
|||
* v3.0, 2015-08-28, fix [#471][bug #471], api response the width and height. 3.0.2
|
||||
* v3.0, 2015-08-25, fix [#367][bug #367], support nginx-rtmp exec. 3.0.1
|
||||
|
||||
### V2 changes
|
||||
## V2 changes
|
||||
|
||||
* <strong>v2.0, 2020-01-25, [2.0 release8(2.0.272)][r2.0r8] released. 87292 lines.</strong>
|
||||
* v2.0, 2020-01-08, Merge [#1554][bug #1554], support logrotate copytruncate. 2.0.272
|
||||
* v2.0, 2020-01-05, Merge [#1551][bug #1551], fix memory leak in RTSP stack. 2.0.270
|
||||
* v2.0, 2019-12-26, For [#1488][bug #1488], pass client ip to http callback. 2.0.269
|
||||
* v2.0, 2019-12-23, Fix [srs-librtmp #22](https://github.com/ossrs/srs-librtmp/issues/22), parse vhost splited by single seperator. 2.0.268
|
||||
* v2.0, 2019-12-23, Fix [srs-librtmp #25](https://github.com/ossrs/srs-librtmp/issues/25), build srs-librtmp on windows. 2.0.267
|
||||
* v2.0, 2019-12-13, Support openssl versions greater than 1.1.0. 2.0.266
|
||||
* <strong>v2.0, 2019-11-29, [2.0 release7(2.0.265)][r2.0r7] released. 86994 lines.</strong>
|
||||
* v2.0, 2019-11-29, For [srs-docker](https://github.com/ossrs/srs-docker/tree/master/2.0), install Cherrypy without sudo. 2.0.265
|
||||
* v2.0, 2019-04-06, For [#1304][bug #1304], Default HSTRS to on. 2.0.264
|
||||
* <strong>v2.0, 2019-04-05, [2.0 release6(2.0.263)][r2.0r6] released. 86994 lines.</strong>
|
||||
* v2.0, 2019-04-05, Merge [#1312][bug #1312], Fix GCC7 build error, this statement may fall through. 2.0.263
|
||||
|
@ -458,7 +561,7 @@ Please select according to languages:
|
|||
* v2.0, 2014-10-18, remove supports for OSX(darwin). 2.0.1.
|
||||
* v2.0, 2014-10-16, revert github srs README to English. 2.0.0.
|
||||
|
||||
### V1 changes
|
||||
## V1 changes
|
||||
|
||||
* <strong>v1.0, 2014-12-05, [1.0 release(1.0.10)][r1.0r0] released. 59391 lines.</strong>
|
||||
* <strong>v1.0, 2014-10-09, [1.0 beta(1.0.0)][r1.0b0] released. 59316 lines.</strong>
|
||||
|
@ -648,8 +751,22 @@ Please select according to languages:
|
|||
* v0.1, 2013-10-18, support rtmp message2chunk protocol(send\_message).
|
||||
* v0.1, 2013-10-17, support rtmp chunk2message protocol(recv\_message).
|
||||
|
||||
### Releases
|
||||
## Releases
|
||||
|
||||
* 2020-03-18, [Release v3.0-b3][r3.0b3], 3.0 beta3, 3.0.134, 122509 lines.
|
||||
* 2020-03-05, [Release v3.0-b2][r3.0b2], 3.0 beta2, 3.0.123, 122170 lines.
|
||||
* 2020-02-14, [Release v3.0-b1][r3.0b1], 3.0 beta1, 3.0.117, 121964 lines.
|
||||
* 2020-02-02, [Release v3.0-b0][r3.0b0], 3.0 beta0, 3.0.112, 121709 lines.
|
||||
* 2020-01-21, [Release v3.0-a9][r3.0a9], 3.0 alpha9, 3.0.105, 121577 lines.
|
||||
* 2020-01-10, [Release v3.0-a8][r3.0a8], 3.0 alpha8, 3.0.97, 121555 lines.
|
||||
* 2019-12-29, [Release v3.0-a7][r3.0a7], 3.0 alpha7, 3.0.90, 116356 lines.
|
||||
* 2019-12-26, [Release v3.0-a6][r3.0a6], 3.0 alpha6, 3.0.85, 116056 lines.
|
||||
* 2019-12-19, [Release v3.0-a5][r3.0a5], 3.0 alpha5, 3.0.75, 115362 lines.
|
||||
* 2019-12-13, [Release v3.0-a4][r3.0a4], 3.0 alpha4, 3.0.71, 112928 lines.
|
||||
* 2019-11-30, [Release v3.0-a3][r3.0a3], 3.0 alpha3, 3.0.67, 110864 lines.
|
||||
* 2019-11-30, [Release v3.0-a2][r3.0a2], 3.0 alpha2, 3.0.66, 110831 lines.
|
||||
* 2019-10-07, [Release v3.0-a1][r3.0a1], 3.0 alpha1, 3.0.60, 107962 lines.
|
||||
* 2019-10-04, [Release v3.0-a0][r3.0a0], 3.0 alpha0, 3.0.56, 107946 lines.
|
||||
* 2017-03-03, [Release v2.0-r0][r2.0r0], 2.0 release0, 2.0.234, 86373 lines.
|
||||
* 2016-11-13, [Release v2.0-b3][r2.0b3], 2.0 beta3, 2.0.223, 86685 lines.
|
||||
* 2016-11-09, [Release v2.0-b2][r2.0b2], 2.0 beta2, 2.0.221, 86691 lines.
|
||||
|
@ -667,7 +784,7 @@ Please select according to languages:
|
|||
* 2014-10-09, [Release v0.9.8][r1.0b0], all bug fixed, 1.0.0, 59316 lines.
|
||||
* 2014-08-03, [Release v0.9.7][r1.0a7], config utest, all bug fixed. 57432 lines.
|
||||
* 2014-07-13, [Release v0.9.6][r1.0a6], core/kernel/rtmp utest, refine bandwidth(as/js/srslibrtmp library). 50029 lines.
|
||||
* 2014-06-27, [Release v0.9.5][r1.0a5], refine perf 3k+ clients, edge token traverse, [srs monitor](http://ossrs.net:1977), 30days online. 41573 lines.
|
||||
* 2014-06-27, [Release v0.9.5][r1.0a5], refine perf 3k+ clients, edge token traverse, 30days online. 41573 lines.
|
||||
* 2014-05-28, [Release v0.9.4][r1.0a4], support heartbeat, tracable log, fix mem leak and bugs. 39200 lines.
|
||||
* 2014-05-18, [Release v0.9.3][r1.0a3], support mips, fms origin, json(http-api). 37594 lines.
|
||||
* 2014-04-28, [Release v0.9.2][r1.0a2], support [dvr][v3_CN_DVR], android, [edge][v3_CN_Edge]. 35255 lines.
|
||||
|
@ -683,13 +800,14 @@ Please select according to languages:
|
|||
* 2013-10-23, [Release v0.1.0][r0.1], support [rtmp FMLE/FFMPEG publish][v1_CN_DeliveryRTMP], vp6. 8287 lines.
|
||||
* 2013-10-17, Created.
|
||||
|
||||
### Compare
|
||||
## Compare
|
||||
|
||||
Comparing with other media servers, SRS is much better and stronger, for details please read Product([CN][v1_CN_Compare]/[EN][v1_EN_Compare]).
|
||||
|
||||
#### Stream Delivery
|
||||
<a name="stream-delivery"></a>
|
||||
**Stream Delivery**
|
||||
|
||||
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
|
||||
| Feature | SRS | NGINX | CRTMPD | AMS | WOWZA |
|
||||
| ----------- | ------- | ----- | --------- | -------- | ------ |
|
||||
| RTMP | Stable | Stable | Stable | Stable | Stable |
|
||||
| HLS | Stable | Stable | X | Stable | Stable |
|
||||
|
@ -699,9 +817,10 @@ Comparing with other media servers, SRS is much better and stronger, for details
|
|||
| MPEG-DASH | Experiment| X | X | X | X |
|
||||
| HTTP Server | Stable | Stable | X | X | Stable |
|
||||
|
||||
#### Cluster
|
||||
<a name="cluster"></a>
|
||||
**Cluster**
|
||||
|
||||
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
|
||||
| Feature | SRS | NGINX | CRTMPD | AMS | WOWZA |
|
||||
| ----------- | ------- | ----- | --------- | -------- | ------ |
|
||||
| RTMP Edge | Stable | X | X | Stable | X |
|
||||
| RTMP Backup | Stable | X | X | X | X |
|
||||
|
@ -709,11 +828,12 @@ Comparing with other media servers, SRS is much better and stronger, for details
|
|||
| Reload | Stable | X | X | X | X |
|
||||
| Forward | Stable | X | X | X | X |
|
||||
| ATC | Stable | X | X | X | X |
|
||||
| KAFKA | Experiment| X | X | X | X |
|
||||
| Docker | Stable | X | X | X | X |
|
||||
|
||||
#### Stream Service
|
||||
<a name="stream-service"></a>
|
||||
**Stream Service**
|
||||
|
||||
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
|
||||
| Feature | SRS | NGINX | CRTMPD | AMS | WOWZA |
|
||||
| ----------- | ------- | ----- | --------- | -------- | ------ |
|
||||
| DVR | Stable | Stable | X | X | Stable |
|
||||
| DVR API | Stable | Stable | X | X | X |
|
||||
|
@ -727,41 +847,46 @@ Comparing with other media servers, SRS is much better and stronger, for details
|
|||
| Security | Stable | Stable | X | X | Stable |
|
||||
| Token Traverse| Stable | X | X | Stable | X |
|
||||
|
||||
#### Efficiency
|
||||
<a name="efficiency"></a>
|
||||
**Efficiency**
|
||||
|
||||
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
|
||||
| Feature | SRS | NGINX | CRTMPD | AMS | WOWZA |
|
||||
| ----------- | ------- | ----- | --------- | -------- | ------ |
|
||||
| Concurrency | 7.5k | 3k | 2k | 2k | 3k |
|
||||
|MultipleProcess| Experiment| Stable | X | X | X |
|
||||
| RTMP Latency| 0.1s | 3s | 3s | 3s | 3s |
|
||||
| HLS Latency | 10s | 30s | X | 30s | 30s |
|
||||
|
||||
#### Stream Caster
|
||||
<a name="stream-caster"></a>
|
||||
**Stream Caster**
|
||||
|
||||
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
|
||||
| Feature | SRS | NGINX | CRTMPD | AMS | WOWZA |
|
||||
| ----------- | ------- | ----- | --------- | -------- | ------ |
|
||||
| Ingest | Stable | X | X | X | X |
|
||||
| Push MPEGTS | Experiment| X | X | X | Stable |
|
||||
| Push RTSP | Experiment| X | Stable | X | Stable |
|
||||
| Push HTTP FLV | Experiment| X | X | X | X |
|
||||
|
||||
#### Debug System
|
||||
<a name="debug-system"></a>
|
||||
**Debug System**
|
||||
|
||||
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
|
||||
| Feature | SRS | NGINX | CRTMPD | AMS | WOWZA |
|
||||
| ----------- | ------- | ----- | --------- | -------- | ------ |
|
||||
| BW check | Stable | X | X | X | X |
|
||||
| Tracable Log | Stable | X | X | X | X |
|
||||
|
||||
#### Docs
|
||||
<a name="docs"></a>
|
||||
**Docs**
|
||||
|
||||
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
|
||||
| Feature | SRS | NGINX | CRTMPD | AMS | WOWZA |
|
||||
| ----------- | ------- | ----- | --------- | -------- | ------ |
|
||||
| Demos | Stable | X | X | X | X |
|
||||
| WIKI(EN+CN) | Stable | EN only | X | X | Stable |
|
||||
|
||||
#### Others
|
||||
<a name="others"></a>
|
||||
**Others**
|
||||
|
||||
| Feature | SRS | NGINX | CRTMPD | FMS | WOWZA |
|
||||
| Feature | SRS | NGINX | CRTMPD | AMS | WOWZA |
|
||||
| ----------- | ------- | ----- | --------- | -------- | ------ |
|
||||
| ARM/MIPS | Stable | Stable | X | X | X |
|
||||
| Client Library| Stable | X | X | X | X |
|
||||
|
@ -775,15 +900,16 @@ Remark:
|
|||
1. Security: The security includes access control, token authentication and referer check.
|
||||
1. Reload: SRS and Nginx supports reload, but nginx-rtmp doesn't.
|
||||
|
||||
### Performance
|
||||
## Performance
|
||||
|
||||
The performance benchmark data and corelative commits are listed here.
|
||||
|
||||
* See also: [Performance for x86/x64 Test Guide][v1_CN_Performance].
|
||||
* See also: [Performance for RaspberryPi][v1_CN_RaspberryPi].
|
||||
* For multiple processes performance, read [go-oryx][oryx].
|
||||
* For multiple processes performance, read [#775: REUSEPORT][bug #775] or OriginCluster([CN][v3_EN_OriginCluster]/[EN][v3_EN_OriginCluster]) or [go-oryx][oryx].
|
||||
|
||||
#### Play RTMP benchmark
|
||||
<a name="play-rtmp-benchmark"></a>
|
||||
**Play RTMP benchmark**
|
||||
|
||||
The data for playing RTMP was benchmarked by [SB][srs-bench]:
|
||||
|
||||
|
@ -803,7 +929,8 @@ The data for playing RTMP was benchmarked by [SB][srs-bench]:
|
|||
| 2014-12-05 | 2.0.57 | 9.0k(9000) | players | 90% | 468MB | [code][p11] |
|
||||
| 2014-12-07 | 2.0.67 | 10k(10000) | players | 95% | 656MB | [code][p12] |
|
||||
|
||||
#### Publish RTMP benchmark
|
||||
<a name="publish-rtmp-benchmark"></a>
|
||||
**Publish RTMP benchmark**
|
||||
|
||||
The data for publishing RTMP was benchmarked by [SB][srs-bench]:
|
||||
|
||||
|
@ -819,7 +946,8 @@ The data for publishing RTMP was benchmarked by [SB][srs-bench]:
|
|||
| 2014-12-04 | 2.0.51 | 2.5k(2500) | publishers | 91% | 259MB | [code][p4] |
|
||||
| 2014-12-04 | 2.0.52 | 4.0k(4000) | publishers | 80% | 331MB | [code][p5] |
|
||||
|
||||
#### Play HTTP FLV benchmark
|
||||
<a name="play-http-flv-benchmark"></a>
|
||||
**Play HTTP FLV benchmark**
|
||||
|
||||
The data for playing HTTP FLV was benchmarked by [SB][srs-bench]:
|
||||
|
||||
|
@ -832,7 +960,8 @@ The data for playing HTTP FLV was benchmarked by [SB][srs-bench]:
|
|||
| 2014-05-24 | 2.0.170 | 3.0k(3000) | players | 89% | 96MB | [code][p19] |
|
||||
| 2014-05-25 | 2.0.171 | 6.0k(6000) | players | 84% | 297MB | [code][p20] |
|
||||
|
||||
#### Latency benchmark
|
||||
<a name="latency-benchmark"></a>
|
||||
**Latency benchmark**
|
||||
|
||||
The latency between encoder and player with realtime config([CN][v3_CN_LowLatency], [EN][v3_EN_LowLatency]):
|
||||
|
|
||||
|
@ -849,7 +978,8 @@ We used FMLE as encoder for benchmark. The latency of server was 0.1s+,
|
|||
and the bottleneck was the encoder. For more information, read
|
||||
[bug #257][bug #257-c0].
|
||||
|
||||
#### HLS overhead
|
||||
<a name="hls-overhead"></a>
|
||||
**HLS overhead**
|
||||
|
||||
About the overhead of HLS overhead, we compared FFMPEG and SRS.
|
||||
|
||||
|
@ -885,7 +1015,7 @@ SRS always use the simplest architecture to solve complex domain problems.
|
|||
* Modularity arch: the main modularity of SRS.
|
||||
* Stream arch: the stream dispatch arch of SRS.
|
||||
|
||||
### System Architecture
|
||||
## System Architecture
|
||||
|
||||
```
|
||||
+------------------------------------------------------+
|
||||
|
@ -903,7 +1033,7 @@ SRS always use the simplest architecture to solve complex domain problems.
|
|||
+------------------------------------------------------+
|
||||
```
|
||||
|
||||
### Modularity Architecture
|
||||
## Modularity Architecture
|
||||
|
||||
```
|
||||
+------------------------------------------------------+
|
||||
|
@ -925,7 +1055,7 @@ Remark:
|
|||
|
||||
1. Modules: SRS supports code-level modularity, read [modules][modules].
|
||||
|
||||
### Stream Architecture
|
||||
## Stream Architecture
|
||||
|
||||
```
|
||||
+---------+ +----------+
|
||||
|
@ -967,32 +1097,31 @@ Remark:
|
|||
1. Streamer: Remuxs other protocols to RTMP, please read [Streamer][v2_CN_Streamer].
|
||||
1. EXEC: Like NGINX-RTMP, EXEC forks external tools for events, please read [ng-exec][v3_CN_NgExec].
|
||||
|
||||
### AUTHORS
|
||||
## AUTHORS
|
||||
|
||||
There are two types of people that have contributed to the SRS project:
|
||||
|
||||
* AUTHORS: Contribute important features. Names of all authors responsed in NetConnection.connect and metadata.
|
||||
* CONTRIBUTORS: Submit patches, report bugs, add translations, help answer newbie questions, and generally make SRS much better.
|
||||
* Maintainers: Contribute and maintain important features. SRS always remembers and thanks you by writing your names in stream metadata.
|
||||
* [Contributors][authors]: Submit patches, report bugs, add translations, help answer newbie questions, and generally make SRS much better.
|
||||
|
||||
About all AUTHORS and CONTRIBUTORS, read [AUTHORS.txt][authors].
|
||||
Maintainers of SRS project:
|
||||
|
||||
* [Winlin](https://github.com/winlinvip): All areas of streaming server and documents.
|
||||
* [Wenjie](https://github.com/wenjiegit): The focus of his work is on the [HDS](https://github.com/simple-rtmp-server/srs/wiki/v2_CN_DeliveryHDS) module.
|
||||
* [Runner365](https://github.com/runner365): The focus of his work is on the [SRT](https://github.com/simple-rtmp-server/srs/wiki/v4_CN_SRTWiki) module.
|
||||
|
||||
A big THANK YOU goes to:
|
||||
|
||||
* All friends of SRS for [big supports][bigthanks].
|
||||
* Genes amd Mabbott for creating [st][st]([state-threads][st2]).
|
||||
* Michael Talyanksy for introducing us to use st.
|
||||
* Roman Arutyunyan for creating [nginx-rtmp][nginx-rtmp] for SRS to refer to.
|
||||
* Joyent for creating [http-parser][http-parser] for http-api for SRS.
|
||||
* Igor Sysoev for creating [nginx][nginx] for SRS to refer to.
|
||||
* [FFMPEG][FFMPEG] and [libx264][libx264] group for SRS to use as transcoder.
|
||||
* Guido van Rossum for creating Python for api-server for SRS.
|
||||
* [Michael Talyanksy](https://github.com/michaeltalyansky) for introducing ST to us.
|
||||
|
||||
### Mirrors
|
||||
## Mirrors
|
||||
|
||||
OSChina: [http://git.oschina.net/winlinvip/srs.oschina][oschina], the GIT usage([CN][v1_CN_Git], [EN][v1_EN_Git])
|
||||
OSChina: [https://gitee.com/winlinvip/srs.oschina][oschina], the GIT usage([CN][v1_CN_Git], [EN][v1_EN_Git])
|
||||
|
||||
```
|
||||
git clone https://git.oschina.net/winlinvip/srs.oschina.git
|
||||
git clone https://gitee.com/winlinvip/srs.oschina.git
|
||||
```
|
||||
|
||||
> Remark: For users in China, recomment to use mirror from CSDN or OSChina, because they are much faster.
|
||||
|
@ -1009,13 +1138,21 @@ Gitlab: [https://gitlab.com/winlinvip/srs-gitlab][gitlab], the GIT usage([CN][v1
|
|||
git clone https://gitlab.com/winlinvip/srs-gitlab.git
|
||||
```
|
||||
|
||||
### System Requirements
|
||||
| Branch | Cost | Size | CMD |
|
||||
| --- | --- | --- | --- |
|
||||
| 3.0release | 2m19.931s | 262MB | git clone -b 3.0release https://gitee.com/winlinvip/srs.oschina.git |
|
||||
| 3.0release | 0m56.515s | 95MB | git clone -b 3.0release --depth=1 https://gitee.com/winlinvip/srs.oschina.git |
|
||||
| develop | 2m22.430s | 234MB | git clone -b develop https://gitee.com/winlinvip/srs.oschina.git |
|
||||
| develop | 0m46.421s | 42MB | git clone -b develop --depth=1 https://gitee.com/winlinvip/srs.oschina.git |
|
||||
| min | 2m22.865s | 217MB | git clone -b min https://gitee.com/winlinvip/srs.oschina.git |
|
||||
| min | 0m36.472s | 11MB | git clone -b min --depth=1 https://gitee.com/winlinvip/srs.oschina.git |
|
||||
|
||||
## System Requirements
|
||||
|
||||
Supported operating systems and hardware:
|
||||
|
||||
* All Linux , both 32 and 64 bits
|
||||
* Apple OSX(Darwin), both 32 and 64bits.
|
||||
* All hardwares with x86/x86_64/arm/mips cpu.
|
||||
* All Linux, both 32 and 64 bits
|
||||
* Other OS, such as Windows, please use [docker][docker-srs3].
|
||||
|
||||
Beijing, 2013.10<br/>
|
||||
Winlin
|
||||
|
@ -1050,8 +1187,8 @@ Winlin
|
|||
[authors]: https://github.com/ossrs/srs/blob/develop/AUTHORS.txt
|
||||
[bigthanks]: https://github.com/ossrs/srs/wiki/v1_CN_Product#bigthanks
|
||||
[st]: https://github.com/winlinvip/state-threads
|
||||
[st2]: http://sourceforge.net/projects/state-threads/
|
||||
[state-threads]: http://sourceforge.net/projects/state-threads/
|
||||
[st2]: https://github.com/ossrs/state-threads/tree/srs
|
||||
[state-threads]: https://github.com/ossrs/state-threads/tree/srs
|
||||
[nginx-rtmp]: https://github.com/arut/nginx-rtmp-module
|
||||
[http-parser]: https://github.com/joyent/http-parser
|
||||
[nginx]: http://nginx.org/
|
||||
|
@ -1059,7 +1196,7 @@ Winlin
|
|||
[libx264]: http://www.videolan.org/
|
||||
[srs]: https://github.com/ossrs/srs
|
||||
[csdn]: https://code.csdn.net/winlinvip/srs-csdn
|
||||
[oschina]: http://git.oschina.net/winlinvip/srs.oschina
|
||||
[oschina]: https://gitee.com/winlinvip/srs.oschina
|
||||
[srs-dolphin]: https://github.com/ossrs/srs-dolphin
|
||||
[oryx]: https://github.com/ossrs/go-oryx
|
||||
[srs-bench]: https://github.com/ossrs/srs-bench
|
||||
|
@ -1069,7 +1206,8 @@ Winlin
|
|||
[console]: http://ossrs.net:1985/console
|
||||
[player]: http://ossrs.net/players/srs_player.html
|
||||
[modules]: https://github.com/ossrs/srs/blob/develop/trunk/modules/readme.txt
|
||||
[docker]: https://github.com/ossrs/srs-docker/tree/centos#usage
|
||||
[docker-srs3]: https://github.com/ossrs/srs-docker#srs3
|
||||
[docker-dev]: https://github.com/ossrs/srs-docker/tree/dev#usage
|
||||
|
||||
[v1_CN_Git]: https://github.com/ossrs/srs/wiki/v1_CN_Git
|
||||
[v1_EN_Git]: https://github.com/ossrs/srs/wiki/v1_EN_Git
|
||||
|
@ -1097,21 +1235,29 @@ Winlin
|
|||
[v3_EN_SampleHTTP]: https://github.com/ossrs/srs/wiki/v3_EN_SampleHTTP
|
||||
[v1_CN_SampleDemo]: https://github.com/ossrs/srs/wiki/v1_CN_SampleDemo
|
||||
[v1_EN_SampleDemo]: https://github.com/ossrs/srs/wiki/v1_EN_SampleDemo
|
||||
[v3_CN_OriginCluster]: https://github.com/ossrs/srs/wiki/v3_CN_OriginCluster
|
||||
[v3_EN_OriginCluster]: https://github.com/ossrs/srs/wiki/v3_EN_OriginCluster
|
||||
[v3_CN_SrsLibrtmp2]: https://github.com/ossrs/srs/wiki/v3_CN_SrsLibrtmp#publish-h264-raw-data
|
||||
[v3_EN_SrsLibrtmp2]: https://github.com/ossrs/srs/wiki/v3_EN_SrsLibrtmp#publish-h264-raw-data
|
||||
[v3_CN_REUSEPORT]: https://github.com/ossrs/srs/wiki/v3_CN_REUSEPORT
|
||||
[v3_EN_REUSEPORT]: https://github.com/ossrs/srs/wiki/v3_EN_REUSEPORT
|
||||
[v1_CN_Sample]: https://github.com/ossrs/srs/wiki/v1_CN_Sample
|
||||
[v1_EN_Sample]: https://github.com/ossrs/srs/wiki/v1_EN_Sample
|
||||
[v1_CN_Product]: https://github.com/ossrs/srs/wiki/v1_CN_Product
|
||||
[v1_EN_Product]: https://github.com/ossrs/srs/wiki/v1_EN_Product
|
||||
[v1-wiki-cn]: https://github.com/ossrs/srs/wiki/v1-wiki-cn
|
||||
[v1-wiki-en]: https://github.com/ossrs/srs/wiki/v1-wiki-en
|
||||
[v2-wiki-cn]: https://github.com/ossrs/srs/wiki/v2-wiki-cn
|
||||
[v2-wiki-en]: https://github.com/ossrs/srs/wiki/v2-wiki-en
|
||||
[v1-wiki-cn]: https://github.com/ossrs/srs/wiki/v1_CN_Home
|
||||
[v1-wiki-en]: https://github.com/ossrs/srs/wiki/v1_EN_Home
|
||||
[v2-wiki-cn]: https://github.com/ossrs/srs/wiki/v2_CN_Home
|
||||
[v2-wiki-en]: https://github.com/ossrs/srs/wiki/v2_EN_Home
|
||||
[v1_CN_Home]: https://github.com/ossrs/srs/wiki/v1_CN_Home
|
||||
[v1_EN_Home]: https://github.com/ossrs/srs/wiki/v1_EN_Home
|
||||
[v2_CN_Home]: https://github.com/ossrs/srs/wiki/v2_CN_Home
|
||||
[v2_EN_Home]: https://github.com/ossrs/srs/wiki/v2_EN_Home
|
||||
[v3_CN_Home]: https://github.com/ossrs/srs/wiki/v3_CN_Home
|
||||
[v3_EN_Home]: https://github.com/ossrs/srs/wiki/v3_EN_Home
|
||||
[donation0]: http://winlinvip.github.io/srs.release/donation/index.html
|
||||
[donation1]: http://www.ossrs.net/srs.release/donation/index.html
|
||||
[donation2]: http://www.ossrs.net/srs.release/donation/paypal.html
|
||||
[donation1]: http://ossrs.net/srs.release/donation/index.html
|
||||
[donation2]: http://ossrs.net/srs.release/donation/paypal.html
|
||||
[donations]: https://github.com/ossrs/srs/blob/develop/DONATIONS.txt
|
||||
|
||||
[v1_CN_Compare]: https://github.com/ossrs/srs/wiki/v1_CN_Compare
|
||||
|
@ -1461,6 +1607,10 @@ Winlin
|
|||
[bug #1339]: https://github.com/ossrs/srs/pull/1339
|
||||
[bug #1312]: https://github.com/ossrs/srs/pull/1312
|
||||
[bug #1304]: https://github.com/ossrs/srs/pull/1304
|
||||
[bug #1524]: https://github.com/ossrs/srs/issues/1524
|
||||
[bug #1488]: https://github.com/ossrs/srs/issues/1488
|
||||
[bug #1551]: https://github.com/ossrs/srs/pull/1551
|
||||
[bug #1554]: https://github.com/ossrs/srs/pull/1554
|
||||
[bug #xxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxx
|
||||
|
||||
[bug #735]: https://github.com/ossrs/srs/issues/735
|
||||
|
@ -1473,16 +1623,75 @@ Winlin
|
|||
[bug #821]: https://github.com/ossrs/srs/issues/821
|
||||
[bug #913]: https://github.com/ossrs/srs/issues/913
|
||||
[bug #460]: https://github.com/ossrs/srs/issues/460
|
||||
[bug #775]: https://github.com/ossrs/srs/issues/775
|
||||
[bug #1057]: https://github.com/ossrs/srs/issues/1057
|
||||
[bug #105]: https://github.com/ossrs/srs/issues/105
|
||||
[bug #727]: https://github.com/ossrs/srs/issues/727
|
||||
[bug #1087]: https://github.com/ossrs/srs/issues/1087
|
||||
[bug #1051]: https://github.com/ossrs/srs/issues/1051
|
||||
[bug #1093]: https://github.com/ossrs/srs/issues/1093
|
||||
[bug #xxxxxxxxxxxxx]: https://github.com/ossrs/srs/issues/xxxxxxxxxxxxx
|
||||
[bug #1501]: https://github.com/ossrs/srs/issues/1501
|
||||
[bug #1229]: https://github.com/ossrs/srs/issues/1229
|
||||
[bug #1042]: https://github.com/ossrs/srs/issues/1042
|
||||
[bug #1445]: https://github.com/ossrs/srs/issues/1445
|
||||
[bug #1506]: https://github.com/ossrs/srs/issues/1506
|
||||
[bug #1520]: https://github.com/ossrs/srs/issues/1520
|
||||
[bug #1223]: https://github.com/ossrs/srs/issues/1223
|
||||
[bug #1508]: https://github.com/ossrs/srs/issues/1508
|
||||
[bug #1535]: https://github.com/ossrs/srs/issues/1535
|
||||
[bug #1537]: https://github.com/ossrs/srs/issues/1537
|
||||
[bug #1538]: https://github.com/ossrs/srs/issues/1538
|
||||
[bug #1282]: https://github.com/ossrs/srs/issues/1282
|
||||
[bug #1105]: https://github.com/ossrs/srs/issues/1105
|
||||
[bug #1544]: https://github.com/ossrs/srs/issues/1544
|
||||
[bug #1255]: https://github.com/ossrs/srs/issues/1255
|
||||
[bug #1543]: https://github.com/ossrs/srs/issues/1543
|
||||
[bug #1509]: https://github.com/ossrs/srs/issues/1509
|
||||
[bug #1575]: https://github.com/ossrs/srs/issues/1575
|
||||
[bug #307]: https://github.com/ossrs/srs/issues/307
|
||||
[bug #1070]: https://github.com/ossrs/srs/issues/1070
|
||||
[bug #1580]: https://github.com/ossrs/srs/issues/1580
|
||||
[bug #1547]: https://github.com/ossrs/srs/issues/1547
|
||||
[bug #1221]: https://github.com/ossrs/srs/issues/1221
|
||||
[bug #1108]: https://github.com/ossrs/srs/issues/1108
|
||||
[bug #703]: https://github.com/ossrs/srs/issues/703
|
||||
[bug #878]: https://github.com/ossrs/srs/issues/878
|
||||
[bug #607]: https://github.com/ossrs/srs/issues/607
|
||||
[bug #1303]: https://github.com/ossrs/srs/issues/1303
|
||||
[bug #1230]: https://github.com/ossrs/srs/issues/1230
|
||||
[bug #1206]: https://github.com/ossrs/srs/issues/1206
|
||||
[bug #939]: https://github.com/ossrs/srs/issues/939
|
||||
[bug #1186]: https://github.com/ossrs/srs/issues/1186
|
||||
[bug #1592]: https://github.com/ossrs/srs/issues/1592
|
||||
[bug #665]: https://github.com/ossrs/srs/issues/665
|
||||
[bug #1595]: https://github.com/ossrs/srs/issues/1595
|
||||
[bug #1601]: https://github.com/ossrs/srs/issues/1601
|
||||
[bug #1579]: https://github.com/ossrs/srs/issues/1579
|
||||
[bug #1598]: https://github.com/ossrs/srs/issues/1598
|
||||
[bug #1634]: https://github.com/ossrs/srs/issues/1634
|
||||
[bug #1594]: https://github.com/ossrs/srs/issues/1594
|
||||
[bug #1630]: https://github.com/ossrs/srs/issues/1630
|
||||
[bug #1635]: https://github.com/ossrs/srs/issues/1635
|
||||
[bug #yyyyyyyyyyyyy]: https://github.com/ossrs/srs/issues/yyyyyyyyyyyyy
|
||||
|
||||
[exo #828]: https://github.com/google/ExoPlayer/pull/828
|
||||
|
||||
[r3.0b3]: https://github.com/ossrs/srs/releases/tag/v3.0-b3
|
||||
[r3.0b2]: https://github.com/ossrs/srs/releases/tag/v3.0-b2
|
||||
[r3.0b1]: https://github.com/ossrs/srs/releases/tag/v3.0-b1
|
||||
[r3.0b0]: https://github.com/ossrs/srs/releases/tag/v3.0-b0
|
||||
[r3.0a9]: https://github.com/ossrs/srs/releases/tag/v3.0-a9
|
||||
[r3.0a8]: https://github.com/ossrs/srs/releases/tag/v3.0-a8
|
||||
[r3.0a7]: https://github.com/ossrs/srs/releases/tag/v3.0-a7
|
||||
[r3.0a6]: https://github.com/ossrs/srs/releases/tag/v3.0-a6
|
||||
[r3.0a5]: https://github.com/ossrs/srs/releases/tag/v3.0-a5
|
||||
[r3.0a4]: https://github.com/ossrs/srs/releases/tag/v3.0-a4
|
||||
[r3.0a3]: https://github.com/ossrs/srs/releases/tag/v3.0-a3
|
||||
[r3.0a2]: https://github.com/ossrs/srs/releases/tag/v3.0-a2
|
||||
[r3.0a1]: https://github.com/ossrs/srs/releases/tag/v3.0-a1
|
||||
[r3.0a0]: https://github.com/ossrs/srs/releases/tag/v3.0-a0
|
||||
[r2.0r8]: https://github.com/ossrs/srs/releases/tag/v2.0-r8
|
||||
[r2.0r7]: https://github.com/ossrs/srs/releases/tag/v2.0-r7
|
||||
[r2.0r6]: https://github.com/ossrs/srs/releases/tag/v2.0-r6
|
||||
[r2.0r5]: https://github.com/ossrs/srs/releases/tag/v2.0-r5
|
||||
[r2.0r4]: https://github.com/ossrs/srs/releases/tag/v2.0-r4
|
||||
|
@ -1524,8 +1733,10 @@ Winlin
|
|||
|
||||
|
||||
[contact]: https://github.com/ossrs/srs/wiki/v1_CN_Contact
|
||||
[v1_CN_Contact]: https://github.com/ossrs/srs/wiki/v1_CN_Contact
|
||||
[v1_EN_Contact]: https://github.com/ossrs/srs/wiki/v1_EN_Contact
|
||||
[more0]: http://winlinvip.github.io/srs.release/releases/
|
||||
[more1]: http://www.ossrs.net/srs.release/releases/
|
||||
[more1]: http://ossrs.net/srs.release/releases/
|
||||
|
||||
[LICENSE]: https://github.com/ossrs/srs/blob/develop/LICENSE
|
||||
[LicenseMixing]: https://github.com/ossrs/srs/wiki/LicenseMixing
|
||||
|
@ -1536,6 +1747,4 @@ Winlin
|
|||
[branch2]: https://github.com/ossrs/srs/tree/2.0release
|
||||
[release2]: https://github.com/ossrs/srs/wiki/v1_CN_Product#release20
|
||||
[release3]: https://github.com/ossrs/srs/wiki/v1_CN_Product#release30
|
||||
[centos0]: http://winlinvip.github.io/srs.release/releases/files/SRS-CentOS6-x86_64-2.0.243.zip
|
||||
[centos1]: http://www.ossrs.net/srs.release/releases/files/SRS-CentOS6-x86_64-2.0.243.zip
|
||||
|
||||
|
|
1
trunk/.gitignore
vendored
1
trunk/.gitignore
vendored
|
@ -2,6 +2,7 @@
|
|||
/*.conf
|
||||
/*.txt
|
||||
/*.flv
|
||||
/*.mp4
|
||||
/doc/frozen*.flv
|
||||
/doc/kungfupanda*.flv
|
||||
/doc/time*.flv
|
||||
|
|
BIN
trunk/3rdparty/fdk-aac-0.1.3.zip
vendored
BIN
trunk/3rdparty/fdk-aac-0.1.3.zip
vendored
Binary file not shown.
BIN
trunk/3rdparty/ffmpeg-3.2.4.zip
vendored
BIN
trunk/3rdparty/ffmpeg-3.2.4.zip
vendored
Binary file not shown.
BIN
trunk/3rdparty/ffmpeg-4.1.zip
vendored
BIN
trunk/3rdparty/ffmpeg-4.1.zip
vendored
Binary file not shown.
17
trunk/3rdparty/gprof/build_gprof2dot.sh
vendored
17
trunk/3rdparty/gprof/build_gprof2dot.sh
vendored
|
@ -1,17 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# check exists.
|
||||
if [[ -d graphviz-2.18 ]]; then
|
||||
echo "graphviz is ok";
|
||||
exit 0;
|
||||
fi
|
||||
|
||||
# check sudoer.
|
||||
sudo echo "ok" > /dev/null 2>&1;
|
||||
ret=$?; if [[ 0 -ne ${ret} ]]; then echo "you must be sudoer"; exit 1; fi
|
||||
|
||||
unzip -q graphviz-2.36.0.zip
|
||||
cd graphviz-2.36.0 && ./configure && make && sudo make install
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then echo "build gprof2dot failed."; exit $ret; fi
|
||||
|
||||
echo "we test in Centos6.0, it's ok"
|
2227
trunk/3rdparty/gprof/gprof2dot.py
vendored
2227
trunk/3rdparty/gprof/gprof2dot.py
vendored
File diff suppressed because it is too large
Load diff
BIN
trunk/3rdparty/gprof/graphviz-2.36.0.zip
vendored
BIN
trunk/3rdparty/gprof/graphviz-2.36.0.zip
vendored
Binary file not shown.
36
trunk/3rdparty/gprof/readme.txt
vendored
36
trunk/3rdparty/gprof/readme.txt
vendored
|
@ -1,36 +1,4 @@
|
|||
gprof图形化输出工具: gprof2dot.py graphviz-2.18.tar.gz build_gprof2dot.sh
|
||||
|
||||
dot:
|
||||
http://www.graphviz.org/
|
||||
http://www.graphviz.org/Download_source.php
|
||||
graphviz-2.18.tar.gz 绘图工具
|
||||
build_gprof2dot.sh 编译graphviz,命令为dot。
|
||||
要求是sudoer,需要sudo make install。
|
||||
|
||||
gprof2dot.py:
|
||||
将gprof的日志绘图。
|
||||
|
||||
使用方法:
|
||||
0. 若需要图形化,编译dot:
|
||||
cd 3rdparty/gprof && bash build_gprof2dot.sh
|
||||
1. srs配置时:
|
||||
./configure --with-gprof
|
||||
脚本会加入编译参数"-pg -lc_p",gcc -g -pg -lc_p -c xxx -o xxx.o,即在configure中打开 Performance="-pg -lc_p"
|
||||
链接时,加入链接选项"-pg",否则无法工作:gcc -pg -o srs xxxx.o,即在configure中打开 PerformanceLink="-pg"
|
||||
2. 编译和启动程序:make && ./objs/srs -c conf/srs.conf
|
||||
退出程序,按CTRL+C,可以看到生成了gmon.out,这个就是性能的统计数据。
|
||||
3. gprof生成报表:
|
||||
gprof -b ./objs/srs gmon.out > gprof.srs.log
|
||||
4. 将报表生成图片:
|
||||
./3rdparty/gprof/gprof2dot.py gprof.srs.log | dot -Tpng -o ~/winlin.png
|
||||
为了压缩仓库尺寸,gprof的文件不在新版本提供,可以切换到2.0分支安装:
|
||||
https://github.com/ossrs/srs/tree/2.0release/trunk/3rdparty/gprof
|
||||
|
||||
缩写语句:
|
||||
# 生成 ~/winlin.log ~/winlin.png
|
||||
rm -f gmon.out; ./objs/srs -c conf/srs.conf
|
||||
# 用户按CTRL+C
|
||||
file="winlin";gprof -b ./objs/srs gmon.out > ~/${file}.log; ./3rdparty/gprof/gprof2dot.py ~/${file}.log | dot -Tpng -o ~/${file}.png
|
||||
|
||||
备注:
|
||||
其实gprof生成的日志就可以看,不一定要图形化。
|
||||
也就是dot和gprof2dot都不用执行。
|
||||
参考:http://www.cs.utah.edu/dept/old/texinfo/as/gprof.html
|
||||
|
|
BIN
trunk/3rdparty/http-parser-2.1.zip
vendored
BIN
trunk/3rdparty/http-parser-2.1.zip
vendored
Binary file not shown.
BIN
trunk/3rdparty/lame-3.99.5.zip
vendored
BIN
trunk/3rdparty/lame-3.99.5.zip
vendored
Binary file not shown.
BIN
trunk/3rdparty/nginx-1.5.7.zip
vendored
BIN
trunk/3rdparty/nginx-1.5.7.zip
vendored
Binary file not shown.
19
trunk/3rdparty/patches/1.st.arm.patch
vendored
19
trunk/3rdparty/patches/1.st.arm.patch
vendored
|
@ -1,19 +0,0 @@
|
|||
*** md.h Fri Oct 2 02:46:43 2009
|
||||
--- ../st-1.9-patch/md.h Mon Mar 16 15:11:49 2015
|
||||
***************
|
||||
*** 422,428 ****
|
||||
#define MD_STACK_GROWS_DOWN
|
||||
|
||||
#if defined(__GLIBC__) && __GLIBC__ >= 2
|
||||
! #define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[20]
|
||||
#else
|
||||
#error "ARM/Linux pre-glibc2 not supported yet"
|
||||
#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */
|
||||
--- 422,428 ----
|
||||
#define MD_STACK_GROWS_DOWN
|
||||
|
||||
#if defined(__GLIBC__) && __GLIBC__ >= 2
|
||||
! #define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[8]
|
||||
#else
|
||||
#error "ARM/Linux pre-glibc2 not supported yet"
|
||||
#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */
|
16
trunk/3rdparty/patches/2.http.parser.patch
vendored
16
trunk/3rdparty/patches/2.http.parser.patch
vendored
|
@ -1,16 +0,0 @@
|
|||
*** Makefile Wed Mar 27 06:35:20 2013
|
||||
--- ../http-parser-2.1-patch/Makefile Mon Mar 16 15:25:59 2015
|
||||
***************
|
||||
*** 12,17 ****
|
||||
--- 12,22 ----
|
||||
CFLAGS_FAST = $(CFLAGS) -O3 $(CFLAGS_FAST_EXTRA)
|
||||
CFLAGS_LIB = $(CFLAGS_FAST) -fPIC
|
||||
|
||||
+ # patch by winlin
|
||||
+ CPPFLAGS_FAST = $(CPPFLAGS_DEBUG)
|
||||
+ CFLAGS_FAST = $(CFLAGS_DEBUG)
|
||||
+ CFLAGS_LIB = $(CFLAGS_FAST) -fPIC
|
||||
+
|
||||
test: test_g test_fast
|
||||
./test_g
|
||||
./test_fast
|
19
trunk/3rdparty/patches/3.st.osx.kqueue.patch
vendored
19
trunk/3rdparty/patches/3.st.osx.kqueue.patch
vendored
|
@ -1,19 +0,0 @@
|
|||
*** io.c Fri Oct 2 06:49:07 2009
|
||||
--- ../st-1.9-patch/io.c Mon Mar 16 15:06:28 2015
|
||||
***************
|
||||
*** 89,94 ****
|
||||
--- 89,102 ----
|
||||
if (fdlim > 0 && rlim.rlim_max > (rlim_t) fdlim) {
|
||||
rlim.rlim_max = fdlim;
|
||||
}
|
||||
+
|
||||
+ /* when rlimit max is negative, for example, osx, use cur directly. */
|
||||
+ /* @see https://github.com/winlinvip/simple-rtmp-server/issues/336 */
|
||||
+ if ((int)rlim.rlim_max < 0) {
|
||||
+ _st_osfd_limit = (int)(fdlim > 0? fdlim : rlim.rlim_cur);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
rlim.rlim_cur = rlim.rlim_max;
|
||||
if (setrlimit(RLIMIT_NOFILE, &rlim) < 0)
|
||||
return -1;
|
|
@ -1,15 +0,0 @@
|
|||
*** Makefile Fri Oct 2 06:55:03 2009
|
||||
--- ../st-1.9-patch/Makefile Mon Mar 16 15:30:35 2015
|
||||
***************
|
||||
*** 310,315 ****
|
||||
--- 310,319 ----
|
||||
EXAMPLES =
|
||||
endif
|
||||
|
||||
+ # disable examples for ubuntu crossbuild failed.
|
||||
+ # @see https://github.com/winlinvip/simple-rtmp-server/issues/308
|
||||
+ EXAMPLES =
|
||||
+
|
||||
ifeq ($(OS), DARWIN)
|
||||
LINKNAME = libst.$(DSO_SUFFIX)
|
||||
SONAME = libst.$(MAJOR).$(DSO_SUFFIX)
|
19
trunk/3rdparty/patches/5.x264.osx.gcc.patch
vendored
19
trunk/3rdparty/patches/5.x264.osx.gcc.patch
vendored
|
@ -1,19 +0,0 @@
|
|||
*** configure Sat Nov 30 05:45:08 2013
|
||||
--- ../x264-snapshot-20131129-2245-stable-patch/configure Tue Mar 17 21:42:24 2015
|
||||
***************
|
||||
*** 466,472 ****
|
||||
;;
|
||||
darwin*)
|
||||
SYS="MACOSX"
|
||||
! CFLAGS="$CFLAGS -falign-loops=16"
|
||||
libm="-lm"
|
||||
if [ "$pic" = "no" ]; then
|
||||
cc_check "" -mdynamic-no-pic && CFLAGS="$CFLAGS -mdynamic-no-pic"
|
||||
--- 466,472 ----
|
||||
;;
|
||||
darwin*)
|
||||
SYS="MACOSX"
|
||||
! CFLAGS="$CFLAGS"
|
||||
libm="-lm"
|
||||
if [ "$pic" = "no" ]; then
|
||||
cc_check "" -mdynamic-no-pic && CFLAGS="$CFLAGS -mdynamic-no-pic"
|
13
trunk/3rdparty/patches/6.ffmpeg.speex.patch
vendored
13
trunk/3rdparty/patches/6.ffmpeg.speex.patch
vendored
|
@ -1,13 +0,0 @@
|
|||
--- configure 2017-02-10 21:25:25.000000000 +0800
|
||||
+++ ../ffmpeg-3.2.4-patch/configure 2017-02-13 22:39:22.676288196 +0800
|
||||
@@ -5739,7 +5739,9 @@
|
||||
enabled libsnappy && require snappy snappy-c.h snappy_compress -lsnappy
|
||||
enabled libsoxr && require libsoxr soxr.h soxr_create -lsoxr && LIBSOXR="-lsoxr"
|
||||
enabled libssh && require_pkg_config libssh libssh/sftp.h sftp_init
|
||||
-enabled libspeex && require_pkg_config speex speex/speex.h speex_decoder_init -lspeex
|
||||
+enabled libspeex && { use_pkg_config speex speex/speex.h speex_decoder_init -lspeex ||
|
||||
+ { require libspeex speex/speex.h speex_decoder_init -lspeex &&
|
||||
+ warn "using libspeex without pkg-config"; } }
|
||||
enabled libtesseract && require_pkg_config tesseract tesseract/capi.h TessBaseAPICreate
|
||||
enabled libtheora && require libtheora theora/theoraenc.h th_info_init -ltheoraenc -ltheoradec -logg
|
||||
enabled libtwolame && require libtwolame twolame.h twolame_init -ltwolame &&
|
13
trunk/3rdparty/patches/6.st.osx10.14.build.patch
vendored
13
trunk/3rdparty/patches/6.st.osx10.14.build.patch
vendored
|
@ -1,13 +0,0 @@
|
|||
--- Makefile 2018-10-28 13:49:27.000000000 +0800
|
||||
+++ ../st-1.9-patch/Makefile 2018-10-28 13:50:07.000000000 +0800
|
||||
@@ -139,8 +139,8 @@ CFLAGS += -arch ppc
|
||||
LDFLAGS += -arch ppc
|
||||
endif
|
||||
ifeq ($(INTEL), yes)
|
||||
-CFLAGS += -arch i386 -arch x86_64
|
||||
-LDFLAGS += -arch i386 -arch x86_64
|
||||
+CFLAGS += -arch x86_64
|
||||
+LDFLAGS += -arch x86_64
|
||||
endif
|
||||
LDFLAGS += -dynamiclib -install_name /sw/lib/libst.$(MAJOR).$(DSO_SUFFIX) -compatibility_version $(MAJOR) -current_version $(VERSION)
|
||||
OTHER_FLAGS = -Wall
|
12
trunk/3rdparty/patches/7.http.parser.patch
vendored
12
trunk/3rdparty/patches/7.http.parser.patch
vendored
|
@ -1,12 +0,0 @@
|
|||
--- Makefile 2019-04-05 19:43:32.000000000 +0800
|
||||
+++ ../http-parser-2.1-patch/Makefile 2019-04-05 19:50:26.000000000 +0800
|
||||
@@ -7,7 +7,8 @@ CPPFLAGS_DEBUG += $(CPPFLAGS_DEBUG_EXTRA
|
||||
CPPFLAGS_FAST = $(CPPFLAGS) -DHTTP_PARSER_STRICT=0
|
||||
CPPFLAGS_FAST += $(CPPFLAGS_FAST_EXTRA)
|
||||
|
||||
-CFLAGS += -Wall -Wextra -Werror
|
||||
+# patch by winlin
|
||||
+CFLAGS += -Wall -Wextra
|
||||
CFLAGS_DEBUG = $(CFLAGS) -O0 -g $(CFLAGS_DEBUG_EXTRA)
|
||||
CFLAGS_FAST = $(CFLAGS) -O3 $(CFLAGS_FAST_EXTRA)
|
||||
CFLAGS_LIB = $(CFLAGS_FAST) -fPIC
|
BIN
trunk/3rdparty/speex-1.2rc1.zip
vendored
BIN
trunk/3rdparty/speex-1.2rc1.zip
vendored
Binary file not shown.
BIN
trunk/3rdparty/st-1.9.zip
vendored
BIN
trunk/3rdparty/st-1.9.zip
vendored
Binary file not shown.
4
trunk/3rdparty/st-srs/.gitignore
vendored
Normal file
4
trunk/3rdparty/st-srs/.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
DARWIN_*_DBG
|
||||
LINUX_*_DBG
|
||||
obj
|
||||
st.pc
|
474
trunk/3rdparty/st-srs/Makefile
vendored
Normal file
474
trunk/3rdparty/st-srs/Makefile
vendored
Normal file
|
@ -0,0 +1,474 @@
|
|||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (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.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is the Netscape Portable Runtime library.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s): Silicon Graphics, Inc.
|
||||
#
|
||||
# Portions created by SGI are Copyright (C) 2000-2001 Silicon
|
||||
# Graphics, Inc. All Rights Reserved.
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU General Public License Version 2 or later (the
|
||||
# "GPL"), in which case the provisions of the GPL are applicable
|
||||
# instead of those above. If you wish to allow use of your
|
||||
# version of this file only under the terms of the GPL and not to
|
||||
# allow others to use your version of this file under the MPL,
|
||||
# indicate your decision by deleting the provisions above and
|
||||
# replace them with the notice and other provisions required by
|
||||
# the GPL. If you do not delete the provisions above, a recipient
|
||||
# may use your version of this file under either the MPL or the
|
||||
# GPL.
|
||||
|
||||
# This is the full version of the libst library - modify carefully
|
||||
VERSION = 1.9
|
||||
|
||||
##########################
|
||||
# Supported OSes:
|
||||
#
|
||||
#OS = AIX
|
||||
#OS = CYGWIN
|
||||
#OS = DARWIN
|
||||
#OS = FREEBSD
|
||||
#OS = HPUX
|
||||
#OS = HPUX_64
|
||||
#OS = IRIX
|
||||
#OS = IRIX_64
|
||||
#OS = LINUX
|
||||
#OS = NETBSD
|
||||
#OS = OPENBSD
|
||||
#OS = OSF1
|
||||
#OS = SOLARIS
|
||||
#OS = SOLARIS_64
|
||||
|
||||
# Please see the "Other possible defines" section below for
|
||||
# possible compilation options.
|
||||
##########################
|
||||
|
||||
CC = cc
|
||||
AR = ar
|
||||
LD = ld
|
||||
RANLIB = ranlib
|
||||
LN = ln
|
||||
|
||||
SHELL = /bin/sh
|
||||
ECHO = /bin/echo
|
||||
|
||||
BUILD = DBG
|
||||
TARGETDIR = $(OS)_$(shell uname -r)_$(BUILD)
|
||||
|
||||
DEFINES = -D$(OS)
|
||||
CFLAGS =
|
||||
SFLAGS =
|
||||
ARFLAGS = -rv
|
||||
LNFLAGS = -s
|
||||
DSO_SUFFIX = so
|
||||
|
||||
MAJOR = $(shell echo $(VERSION) | sed 's/^\([^\.]*\).*/\1/')
|
||||
DESC = st.pc
|
||||
|
||||
##########################
|
||||
# Platform section.
|
||||
# Possible targets:
|
||||
|
||||
TARGETS = aix-debug aix-optimized \
|
||||
cygwin-debug cygwin-optimized \
|
||||
darwin-debug darwin-optimized \
|
||||
freebsd-debug freebsd-optimized \
|
||||
hpux-debug hpux-optimized \
|
||||
hpux-64-debug hpux-64-optimized \
|
||||
irix-n32-debug irix-n32-optimized \
|
||||
irix-64-debug irix-64-optimized \
|
||||
linux-debug linux-optimized \
|
||||
netbsd-debug netbsd-optimized \
|
||||
openbsd-debug openbsd-optimized \
|
||||
osf1-debug osf1-optimized \
|
||||
solaris-debug solaris-optimized \
|
||||
solaris-64-debug solaris-64-optimized
|
||||
|
||||
#
|
||||
# Platform specifics
|
||||
#
|
||||
|
||||
ifeq ($(OS), AIX)
|
||||
AIX_VERSION = $(shell uname -v).$(shell uname -r)
|
||||
TARGETDIR = $(OS)_$(AIX_VERSION)_$(BUILD)
|
||||
CC = xlC
|
||||
STATIC_ONLY = yes
|
||||
ifeq ($(BUILD), OPT)
|
||||
OTHER_FLAGS = -w
|
||||
endif
|
||||
ifneq ($(filter-out 4.1 4.2, $(AIX_VERSION)),)
|
||||
DEFINES += -DMD_HAVE_SOCKLEN_T
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(OS), CYGWIN)
|
||||
TARGETDIR = $(OS)_$(BUILD)
|
||||
CC = gcc
|
||||
LD = gcc
|
||||
DSO_SUFFIX = dll
|
||||
SLIBRARY = $(TARGETDIR)/libst.dll.a
|
||||
DLIBRARY = $(TARGETDIR)/libst.dll
|
||||
DEF_FILE = $(TARGETDIR)/libst.def
|
||||
LDFLAGS = libst.def -shared --enable-auto-image-base -Wl,--output-def,$(DEF_FILE),--out-implib,$(SLIBRARY)
|
||||
OTHER_FLAGS = -Wall
|
||||
endif
|
||||
|
||||
ifeq ($(OS), DARWIN)
|
||||
LD = cc
|
||||
SFLAGS = -fPIC -fno-common
|
||||
DSO_SUFFIX = dylib
|
||||
RELEASE = $(shell uname -r | cut -d. -f1)
|
||||
PPC = $(shell test $(RELEASE) -le 9 && echo yes)
|
||||
INTEL = $(shell test $(RELEASE) -ge 9 && echo yes)
|
||||
ifeq ($(PPC), yes)
|
||||
CFLAGS += -arch ppc
|
||||
LDFLAGS += -arch ppc
|
||||
endif
|
||||
ifeq ($(INTEL), yes)
|
||||
CFLAGS += -arch i386 -arch x86_64
|
||||
LDFLAGS += -arch i386 -arch x86_64
|
||||
endif
|
||||
LDFLAGS += -dynamiclib -install_name /sw/lib/libst.$(MAJOR).$(DSO_SUFFIX) -compatibility_version $(MAJOR) -current_version $(VERSION)
|
||||
OTHER_FLAGS = -Wall
|
||||
endif
|
||||
|
||||
ifeq ($(OS), FREEBSD)
|
||||
SFLAGS = -fPIC
|
||||
LDFLAGS = -shared -soname=$(SONAME) -lc
|
||||
OTHER_FLAGS = -Wall
|
||||
ifeq ($(shell test -f /usr/include/sys/event.h && echo yes), yes)
|
||||
DEFINES += -DMD_HAVE_KQUEUE
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq (HPUX, $(findstring HPUX, $(OS)))
|
||||
ifeq ($(OS), HPUX_64)
|
||||
DEFINES = -DHPUX
|
||||
CFLAGS = -Ae +DD64 +Z
|
||||
else
|
||||
CFLAGS = -Ae +DAportable +Z
|
||||
endif
|
||||
RANLIB = true
|
||||
LDFLAGS = -b
|
||||
DSO_SUFFIX = sl
|
||||
endif
|
||||
|
||||
ifeq (IRIX, $(findstring IRIX, $(OS)))
|
||||
ifeq ($(OS), IRIX_64)
|
||||
DEFINES = -DIRIX
|
||||
ABIFLAG = -64
|
||||
else
|
||||
ABIFLAG = -n32
|
||||
endif
|
||||
RANLIB = true
|
||||
CFLAGS = $(ABIFLAG) -mips3
|
||||
LDFLAGS = $(ABIFLAG) -shared
|
||||
OTHER_FLAGS = -fullwarn
|
||||
endif
|
||||
|
||||
ifeq ($(OS), LINUX)
|
||||
EXTRA_OBJS = $(TARGETDIR)/md.o
|
||||
SFLAGS = -fPIC
|
||||
LDFLAGS = -shared -soname=$(SONAME) -lc
|
||||
OTHER_FLAGS = -Wall
|
||||
ifeq ($(shell test -f /usr/include/sys/epoll.h && echo yes), yes)
|
||||
DEFINES += -DMD_HAVE_EPOLL
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(OS), NETBSD)
|
||||
SFLAGS = -fPIC
|
||||
LDFLAGS = -shared -soname=$(SONAME) -lc
|
||||
OTHER_FLAGS = -Wall
|
||||
endif
|
||||
|
||||
ifeq ($(OS), OPENBSD)
|
||||
SFLAGS = -fPIC
|
||||
LDFLAGS = -shared -soname=$(SONAME) -lc
|
||||
OTHER_FLAGS = -Wall
|
||||
ifeq ($(shell test -f /usr/include/sys/event.h && echo yes), yes)
|
||||
DEFINES += -DMD_HAVE_KQUEUE
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(OS), OSF1)
|
||||
RANLIB = true
|
||||
LDFLAGS = -shared -all -expect_unresolved "*"
|
||||
endif
|
||||
|
||||
ifeq (SOLARIS, $(findstring SOLARIS, $(OS)))
|
||||
TARGETDIR = $(OS)_$(shell uname -r | sed 's/^5/2/')_$(BUILD)
|
||||
CC = gcc
|
||||
LD = gcc
|
||||
RANLIB = true
|
||||
LDFLAGS = -G
|
||||
OTHER_FLAGS = -Wall
|
||||
ifeq ($(OS), SOLARIS_64)
|
||||
DEFINES = -DSOLARIS
|
||||
CFLAGS += -m64
|
||||
LDFLAGS += -m64
|
||||
endif
|
||||
endif
|
||||
|
||||
#
|
||||
# End of platform section.
|
||||
##########################
|
||||
|
||||
|
||||
ifeq ($(BUILD), OPT)
|
||||
OTHER_FLAGS += -O
|
||||
else
|
||||
OTHER_FLAGS += -g
|
||||
DEFINES += -DDEBUG
|
||||
endif
|
||||
|
||||
##########################
|
||||
# Other possible defines:
|
||||
# To use poll(2) instead of select(2) for events checking:
|
||||
# DEFINES += -DUSE_POLL
|
||||
# You may prefer to use select for applications that have many threads
|
||||
# using one file descriptor, and poll for applications that have many
|
||||
# different file descriptors. With USE_POLL poll() is called with at
|
||||
# least one pollfd per I/O-blocked thread, so 1000 threads sharing one
|
||||
# descriptor will poll 1000 identical pollfds and select would be more
|
||||
# efficient. But if the threads all use different descriptors poll()
|
||||
# may be better depending on your operating system's implementation of
|
||||
# poll and select. Really, it's up to you. Oh, and on some platforms
|
||||
# poll() fails with more than a few dozen descriptors.
|
||||
#
|
||||
# Some platforms allow to define FD_SETSIZE (if select() is used), e.g.:
|
||||
# DEFINES += -DFD_SETSIZE=4096
|
||||
#
|
||||
# To use malloc(3) instead of mmap(2) for stack allocation:
|
||||
# DEFINES += -DMALLOC_STACK
|
||||
#
|
||||
# To provision more than the default 16 thread-specific-data keys
|
||||
# (but not too many!):
|
||||
# DEFINES += -DST_KEYS_MAX=<n>
|
||||
#
|
||||
# To start with more than the default 64 initial pollfd slots
|
||||
# (but the table grows dynamically anyway):
|
||||
# DEFINES += -DST_MIN_POLLFDS_SIZE=<n>
|
||||
#
|
||||
# Note that you can also add these defines by specifying them as
|
||||
# make/gmake arguments (without editing this Makefile). For example:
|
||||
#
|
||||
# make EXTRA_CFLAGS=-DUSE_POLL <target>
|
||||
#
|
||||
# (replace make with gmake if needed).
|
||||
#
|
||||
# You can also modify the default selection of an alternative event
|
||||
# notification mechanism. E.g., to enable kqueue(2) support (if it's not
|
||||
# enabled by default):
|
||||
#
|
||||
# gmake EXTRA_CFLAGS=-DMD_HAVE_KQUEUE <target>
|
||||
#
|
||||
# or to disable default epoll(4) support:
|
||||
#
|
||||
# make EXTRA_CFLAGS=-UMD_HAVE_EPOLL <target>
|
||||
#
|
||||
##########################
|
||||
|
||||
CFLAGS += $(DEFINES) $(OTHER_FLAGS) $(EXTRA_CFLAGS)
|
||||
|
||||
OBJS = $(TARGETDIR)/sched.o \
|
||||
$(TARGETDIR)/stk.o \
|
||||
$(TARGETDIR)/sync.o \
|
||||
$(TARGETDIR)/key.o \
|
||||
$(TARGETDIR)/io.o \
|
||||
$(TARGETDIR)/event.o
|
||||
OBJS += $(EXTRA_OBJS)
|
||||
HEADER = $(TARGETDIR)/st.h
|
||||
SLIBRARY = $(TARGETDIR)/libst.a
|
||||
DLIBRARY = $(TARGETDIR)/libst.$(DSO_SUFFIX).$(VERSION)
|
||||
EXAMPLES = examples
|
||||
|
||||
LINKNAME = libst.$(DSO_SUFFIX)
|
||||
SONAME = libst.$(DSO_SUFFIX).$(MAJOR)
|
||||
FULLNAME = libst.$(DSO_SUFFIX).$(VERSION)
|
||||
|
||||
ifeq ($(OS), CYGWIN)
|
||||
SONAME = cygst.$(DSO_SUFFIX)
|
||||
SLIBRARY = $(TARGETDIR)/libst.dll.a
|
||||
DLIBRARY = $(TARGETDIR)/$(SONAME)
|
||||
LINKNAME =
|
||||
# examples directory does not compile under cygwin
|
||||
EXAMPLES =
|
||||
endif
|
||||
|
||||
# for SRS
|
||||
# disable examples for ubuntu crossbuild failed.
|
||||
# @see https://github.com/winlinvip/simple-rtmp-server/issues/308
|
||||
EXAMPLES =
|
||||
|
||||
ifeq ($(OS), DARWIN)
|
||||
LINKNAME = libst.$(DSO_SUFFIX)
|
||||
SONAME = libst.$(MAJOR).$(DSO_SUFFIX)
|
||||
FULLNAME = libst.$(VERSION).$(DSO_SUFFIX)
|
||||
endif
|
||||
|
||||
ifeq ($(STATIC_ONLY), yes)
|
||||
LIBRARIES = $(SLIBRARY)
|
||||
else
|
||||
LIBRARIES = $(SLIBRARY) $(DLIBRARY)
|
||||
endif
|
||||
|
||||
ifeq ($(OS),)
|
||||
ST_ALL = unknown
|
||||
else
|
||||
ST_ALL = $(TARGETDIR) $(LIBRARIES) $(HEADER) $(EXAMPLES) $(DESC)
|
||||
endif
|
||||
|
||||
all: $(ST_ALL)
|
||||
|
||||
unknown:
|
||||
@echo
|
||||
@echo "Please specify one of the following targets:"
|
||||
@echo
|
||||
@for target in $(TARGETS); do echo $$target; done
|
||||
@echo
|
||||
|
||||
st.pc: st.pc.in
|
||||
sed "s/@VERSION@/${VERSION}/g" < $< > $@
|
||||
|
||||
$(TARGETDIR):
|
||||
if [ ! -d $(TARGETDIR) ]; then mkdir $(TARGETDIR); fi
|
||||
|
||||
$(SLIBRARY): $(OBJS)
|
||||
$(AR) $(ARFLAGS) $@ $(OBJS)
|
||||
$(RANLIB) $@
|
||||
rm -f obj; $(LN) $(LNFLAGS) $(TARGETDIR) obj
|
||||
|
||||
$(DLIBRARY): $(OBJS:%.o=%-pic.o)
|
||||
$(LD) $(LDFLAGS) $^ -o $@
|
||||
if test "$(LINKNAME)"; then \
|
||||
cd $(TARGETDIR); \
|
||||
rm -f $(SONAME) $(LINKNAME); \
|
||||
$(LN) $(LNFLAGS) $(FULLNAME) $(SONAME); \
|
||||
$(LN) $(LNFLAGS) $(FULLNAME) $(LINKNAME); \
|
||||
fi
|
||||
|
||||
$(HEADER): public.h
|
||||
rm -f $@
|
||||
cp public.h $@
|
||||
|
||||
$(TARGETDIR)/md.o: md.S
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
$(TARGETDIR)/%.o: %.c common.h md.h
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
examples::
|
||||
@echo Making $@
|
||||
@cd $@; $(MAKE) CC="$(CC)" CFLAGS="$(CFLAGS)" OS="$(OS)" TARGETDIR="$(TARGETDIR)"
|
||||
|
||||
clean:
|
||||
rm -rf *_OPT *_DBG obj st.pc
|
||||
|
||||
##########################
|
||||
# Pattern rules:
|
||||
|
||||
ifneq ($(SFLAGS),)
|
||||
# Compile with shared library options if it's a C file
|
||||
$(TARGETDIR)/%-pic.o: %.c common.h md.h
|
||||
$(CC) $(CFLAGS) $(SFLAGS) -c $< -o $@
|
||||
endif
|
||||
|
||||
# Compile assembly as normal or C as normal if no SFLAGS
|
||||
%-pic.o: %.o
|
||||
rm -f $@; $(LN) $(LNFLAGS) $(<F) $@
|
||||
|
||||
##########################
|
||||
# Target rules:
|
||||
|
||||
default-debug:
|
||||
. ./osguess.sh; $(MAKE) OS="$$OS" BUILD="DBG"
|
||||
default default-optimized:
|
||||
. ./osguess.sh; $(MAKE) OS="$$OS" BUILD="OPT"
|
||||
|
||||
aix-debug:
|
||||
$(MAKE) OS="AIX" BUILD="DBG"
|
||||
aix-optimized:
|
||||
$(MAKE) OS="AIX" BUILD="OPT"
|
||||
|
||||
cygwin-debug:
|
||||
$(MAKE) OS="CYGWIN" BUILD="DBG"
|
||||
cygwin-optimized:
|
||||
$(MAKE) OS="CYGWIN" BUILD="OPT"
|
||||
|
||||
darwin-debug:
|
||||
$(MAKE) OS="DARWIN" BUILD="DBG"
|
||||
darwin-optimized:
|
||||
$(MAKE) OS="DARWIN" BUILD="OPT"
|
||||
|
||||
freebsd-debug:
|
||||
$(MAKE) OS="FREEBSD" BUILD="DBG"
|
||||
freebsd-optimized:
|
||||
$(MAKE) OS="FREEBSD" BUILD="OPT"
|
||||
|
||||
hpux-debug:
|
||||
$(MAKE) OS="HPUX" BUILD="DBG"
|
||||
hpux-optimized:
|
||||
$(MAKE) OS="HPUX" BUILD="OPT"
|
||||
hpux-64-debug:
|
||||
$(MAKE) OS="HPUX_64" BUILD="DBG"
|
||||
hpux-64-optimized:
|
||||
$(MAKE) OS="HPUX_64" BUILD="OPT"
|
||||
|
||||
irix-n32-debug:
|
||||
$(MAKE) OS="IRIX" BUILD="DBG"
|
||||
irix-n32-optimized:
|
||||
$(MAKE) OS="IRIX" BUILD="OPT"
|
||||
irix-64-debug:
|
||||
$(MAKE) OS="IRIX_64" BUILD="DBG"
|
||||
irix-64-optimized:
|
||||
$(MAKE) OS="IRIX_64" BUILD="OPT"
|
||||
|
||||
linux-debug:
|
||||
$(MAKE) OS="LINUX" BUILD="DBG"
|
||||
linux-optimized:
|
||||
$(MAKE) OS="LINUX" BUILD="OPT"
|
||||
# compatibility
|
||||
linux-ia64-debug: linux-debug
|
||||
linux-ia64-optimized: linux-optimized
|
||||
|
||||
netbsd-debug:
|
||||
$(MAKE) OS="NETBSD" BUILD="DBG"
|
||||
netbsd-optimized:
|
||||
$(MAKE) OS="NETBSD" BUILD="OPT"
|
||||
|
||||
openbsd-debug:
|
||||
$(MAKE) OS="OPENBSD" BUILD="DBG"
|
||||
openbsd-optimized:
|
||||
$(MAKE) OS="OPENBSD" BUILD="OPT"
|
||||
|
||||
osf1-debug:
|
||||
$(MAKE) OS="OSF1" BUILD="DBG"
|
||||
osf1-optimized:
|
||||
$(MAKE) OS="OSF1" BUILD="OPT"
|
||||
|
||||
solaris-debug:
|
||||
$(MAKE) OS="SOLARIS" BUILD="DBG"
|
||||
solaris-optimized:
|
||||
$(MAKE) OS="SOLARIS" BUILD="OPT"
|
||||
solaris-64-debug:
|
||||
$(MAKE) OS="SOLARIS_64" BUILD="DBG"
|
||||
solaris-64-optimized:
|
||||
$(MAKE) OS="SOLARIS_64" BUILD="OPT"
|
||||
|
||||
##########################
|
||||
|
394
trunk/3rdparty/st-srs/README
vendored
Normal file
394
trunk/3rdparty/st-srs/README
vendored
Normal file
|
@ -0,0 +1,394 @@
|
|||
WELCOME!
|
||||
|
||||
The State Threads Library is a small application library which provides
|
||||
a foundation for writing fast and highly scalable Internet applications
|
||||
(such as web servers, proxy servers, mail transfer agents, and so on,
|
||||
really any network-data-driven application) on UNIX-like platforms. It
|
||||
combines the simplicity of the multithreaded programming paradigm, in
|
||||
which one thread supports each simultaneous connection, with the
|
||||
performance and scalability of an event-driven state machine
|
||||
architecture. In other words, this library offers a threading API for
|
||||
structuring an Internet application as a state machine. For more
|
||||
details, please see the library documentation in the "docs" directory or
|
||||
on-line at
|
||||
|
||||
http://state-threads.sourceforge.net/docs/
|
||||
|
||||
The State Threads Project is an open source project for maintaining and
|
||||
enhancing the State Threads Library. For more information about this
|
||||
project, please see
|
||||
|
||||
http://state-threads.sourceforge.net/
|
||||
|
||||
|
||||
BUILDING
|
||||
|
||||
To build the library by hand, use the GNU make utility. Run the make
|
||||
command (e.g., `gmake') with no arguments to display all supported
|
||||
targets.
|
||||
|
||||
To build more or less automatically, first set the CONFIG_GUESS_PATH
|
||||
variable in either osguess.sh or your environment then run "make
|
||||
default" which guesses your OS and builds. Requires the "config.guess"
|
||||
utility from GNU autoconf (not included with ST). You can use one from
|
||||
a larger "main" software project or just use any config.guess available
|
||||
on your system. You can also get it directly from GNU:
|
||||
ftp://ftp.gnu.org/gnu/autoconf/
|
||||
|
||||
To build rpms (RedHat Linux 6.2 or later, Linux/Mandrake, Solaris with
|
||||
gnome, etc.):
|
||||
download the latest st-x.y.tar.gz
|
||||
# rpm -ta st-x.y.tar.gz
|
||||
The .rpms will land in /usr/src/RPMS/<arch>. Install them with:
|
||||
# rpm -i libst*.rpm
|
||||
Requires GNU automake and rpm 3.0.3 or later.
|
||||
|
||||
Debian users:
|
||||
If you run potato, please upgrade to woody.
|
||||
If you run woody, "apt-get install libst-dev" will get you v1.3.
|
||||
If you run testing/unstable, you will get the newest available version.
|
||||
If you *must* have the newest libst in woody, you may follow these
|
||||
not-recommended instructions:
|
||||
1. Add "deb-src <your-favourite-debian-mirror> unstable main" to your
|
||||
/etc/apt/sources.list
|
||||
2. apt-get update
|
||||
3. apt-get source st
|
||||
4. cd st-1.4 (or whatever version you got)
|
||||
5. debuild
|
||||
6. dpkg -i ../*.deb
|
||||
|
||||
If your application uses autoconf to search for dependencies and you
|
||||
want to search for a given version of libst, you can simply add
|
||||
PKG_CHECK_MODULES(MYAPP, st >= 1.3 mumble >= 0.2.23)
|
||||
to your configure.ac/in. This will define @MYAPP_LIBS@ and
|
||||
@MYAPP_CFLAGS@ which you may then use in your Makefile.am/in files to
|
||||
link against mumble and st.
|
||||
|
||||
|
||||
LICENSE
|
||||
|
||||
The State Threads library is a derivative of the Netscape Portable
|
||||
Runtime library (NSPR). All source code in this directory is
|
||||
distributed under the terms of the Mozilla Public License (MPL) version
|
||||
1.1 or the GNU General Public License (GPL) version 2 or later. For
|
||||
more information about these licenses please see
|
||||
http://www.mozilla.org/MPL/ and http://www.gnu.org/copyleft/.
|
||||
|
||||
All source code in the "examples" directory is distributed under the BSD
|
||||
style license.
|
||||
|
||||
|
||||
PLATFORMS
|
||||
|
||||
Please see the "docs/notes.html" file for the list of currently
|
||||
supported platforms.
|
||||
|
||||
|
||||
DEBUGGER SUPPORT
|
||||
|
||||
It's almost impossible to print SP and PC in a portable way. The only
|
||||
way to see thread's stack platform-independently is to actually jump to
|
||||
the saved context. That's what the _st_iterate_threads() function does.
|
||||
Do the following to iterate over all threads:
|
||||
|
||||
- set the _st_iterate_threads_flag to 1 in debugger
|
||||
- set breakpoint at the _st_show_thread_stack() function
|
||||
(which does nothing)
|
||||
- call the _st_iterate_threads() function which jumps to the
|
||||
next thread
|
||||
- at each break you can explore thread's stack
|
||||
- continue
|
||||
- when iteration is complete, you return to the original
|
||||
point (you can see thread id and a message as arguments of
|
||||
the _st_show_thread_stack() function).
|
||||
|
||||
You can call _st_iterate_threads() in three ways:
|
||||
|
||||
- Insert it into your source code at the point you want to
|
||||
go over threads.
|
||||
- Just run application and this function will be called at
|
||||
the first context switch.
|
||||
- Call it directly from the debugger at any point.
|
||||
|
||||
This works with gdb and dbx.
|
||||
|
||||
Example using gdb:
|
||||
|
||||
(gdb) set _st_iterate_threads_flag = 1
|
||||
(gdb) b _st_show_thread_stack
|
||||
...
|
||||
(gdb) call _st_iterate_threads()
|
||||
...
|
||||
(gdb) bt
|
||||
...
|
||||
(gdb) c
|
||||
...
|
||||
(gdb) bt
|
||||
...
|
||||
(gdb) c
|
||||
...
|
||||
and so on...
|
||||
|
||||
_st_iterate_threads_flag will be set to 0 automatically
|
||||
after iteration is over or you can set it to 0 at any time
|
||||
to stop iteration.
|
||||
|
||||
Sometimes gdb complains about SIGSEGV when you call a function
|
||||
directly at gdb command-line. It can be ignored -- just call the
|
||||
same function right away again, it works just fine. For example:
|
||||
|
||||
(gdb) set _st_iterate_threads_flag = 1
|
||||
(gdb) b _st_show_thread_stack
|
||||
Breakpoint 1 at 0x809bbbb: file sched.c, line 856.
|
||||
(gdb) call _st_iterate_threads()
|
||||
Program received signal SIGSEGV, Segmentation fault.
|
||||
....
|
||||
(gdb) # just call the function again:
|
||||
(gdb) call _st_iterate_threads()
|
||||
Breakpoint 1, _st_show_thread_stack (thread=0x4017aee4, messg=0x80ae7a2
|
||||
"Iteration started") at sched.c:856
|
||||
856 }
|
||||
....
|
||||
|
||||
You can use simple gdb command-line scripting to display
|
||||
all threads and their stack traces at once:
|
||||
|
||||
(gdb) while _st_iterate_threads_flag
|
||||
>bt
|
||||
>c
|
||||
>end
|
||||
....
|
||||
|
||||
Another script to stop at the thread with the specific thread id
|
||||
(e.g., 0x40252ee4):
|
||||
|
||||
(gdb) # set the flag again:
|
||||
(gdb) set _st_iterate_threads_flag = 1
|
||||
(gdb) call _st_iterate_threads()
|
||||
Breakpoint 1, _st_show_thread_stack (thread=0x4017aee4, messg=0x80ae7a2
|
||||
"Iteration started") at sched.c:856
|
||||
856 }
|
||||
....
|
||||
(gdb) while thread != 0x40252ee4
|
||||
>c
|
||||
>end
|
||||
....
|
||||
....
|
||||
Breakpoint 1, _st_show_thread_stack (thread=0x40252ee4, messg=0x0) at
|
||||
sched.c:856
|
||||
856 }
|
||||
(gdb) bt
|
||||
....
|
||||
(gdb) # don't want to continue iteration, unset the flag:
|
||||
(gdb) set _st_iterate_threads_flag = 0
|
||||
(gdb) c
|
||||
Continuing.
|
||||
Breakpoint 1, _st_show_thread_stack (thread=0x0, messg=0x80ae78e "Iteration
|
||||
completed")
|
||||
at sched.c:856
|
||||
856 }
|
||||
(gdb) c
|
||||
Continuing.
|
||||
(gdb) return
|
||||
Make selected stack frame return now? (y or n) y
|
||||
#0 0x4011254e in __select ()
|
||||
from /lib/libc.so.6
|
||||
(gdb) detach
|
||||
|
||||
|
||||
CHANGE LOG
|
||||
|
||||
Changes from 1.8 to 1.9.
|
||||
------------------------
|
||||
o Support 32-bit and 64-bit Intel Macs.
|
||||
|
||||
o Added ST_VERSION string, and ST_VERSION_MAJOR and ST_VERSION_MINOR
|
||||
[bug 1796801].
|
||||
|
||||
o Fixed some compiler warnings, based on a patch from Brian Wellington
|
||||
[bug 1932741].
|
||||
|
||||
|
||||
Changes from 1.7 to 1.8.
|
||||
--------------------------
|
||||
o Added support for kqueue and epoll on platforms that support them.
|
||||
Added ability to choose the event notification system at program
|
||||
startup.
|
||||
|
||||
o Long-overdue public definitions of ST_UTIME_NO_TIMEOUT (-1ULL) and
|
||||
ST_UTIME_NO_WAIT (0) [bug 1514436].
|
||||
|
||||
o Documentation patch for st_utime() [bug 1514484].
|
||||
|
||||
o Documentation patch for st_timecache_set() [bug 1514486].
|
||||
|
||||
o Documentation patch for st_netfd_serialize_accept() [bug 1514494].
|
||||
|
||||
o Added st_writev_resid() [rfe 1538344].
|
||||
|
||||
o Added st_readv_resid() [rfe 1538768] and, for symmetry, st_readv().
|
||||
|
||||
|
||||
Changes from 1.6 to 1.7.
|
||||
------------------------
|
||||
o Support glibc 2.4, which breaks programs that manipulate jump buffers.
|
||||
Replaced Linux IA64 special cases with new md.S that covers all
|
||||
Linux.
|
||||
|
||||
|
||||
Changes from 1.5.2 to 1.6.
|
||||
--------------------------
|
||||
none
|
||||
|
||||
|
||||
Changes from 1.5.1 to 1.5.2.
|
||||
----------------------------
|
||||
o Alfred Perlstein's context switch callback feature.
|
||||
|
||||
o Claus Assmann's st_recvmsg/st_sendmsg wrappers.
|
||||
|
||||
o Extra stack padding for platforms that need it.
|
||||
|
||||
o Ron Arts's timeout clarifications in the reference manual.
|
||||
|
||||
o Raymond Bero and Anton Berezin's AMD64 FreeBSD port.
|
||||
|
||||
o Claus Assmann's AMD64 SunOS 5.10 port.
|
||||
|
||||
o Claus Assmann's AMD64 OpenBSD port.
|
||||
|
||||
o Michael Abd-El-Malek's Mac OS X port.
|
||||
|
||||
o Michael Abd-El-Malek's stack printing patch.
|
||||
|
||||
|
||||
Changes from 1.5.0 to 1.5.1.
|
||||
----------------------------
|
||||
o Andreas Gustafsson's USE_POLL fix.
|
||||
|
||||
o Gene's st_set_utime_function() enhancement.
|
||||
|
||||
|
||||
Changes from 1.4 to 1.5.0.
|
||||
--------------------------
|
||||
o Andreas Gustafsson's performance patch.
|
||||
|
||||
o New extensions: Improved DNS resolver, generic LRU cache, in-process
|
||||
DNS cache, and a program to test the resolver and cache.
|
||||
|
||||
o Support for AMD Opteron 64-bit CPUs under Linux.
|
||||
|
||||
o Support for SPARC-64 under Solaris.
|
||||
|
||||
o Andreas Gustafsson's support for VAX under NetBSD.
|
||||
|
||||
o Changed unportable #warning directives in md.h to #error.
|
||||
|
||||
|
||||
Changes from 1.3 to 1.4.
|
||||
------------------------
|
||||
o Andreas Gustafsson's NetBSD port.
|
||||
|
||||
o Wesley W. Terpstra's Darwin (MacOS X) port.
|
||||
|
||||
o Support for many CPU architectures under Linux and *BSD.
|
||||
|
||||
o Renamed private typedefs so they don't conflict with public ones any
|
||||
more.
|
||||
|
||||
o common.h now includes public.h for strict prototyping.
|
||||
|
||||
o Joshua Levy's recommendation to make st_connect() and st_sendto()
|
||||
accept const struct sockaddr pointers, as the originals do.
|
||||
|
||||
o Clarified the documentation regarding blocking vs. non-blocking I/O.
|
||||
|
||||
o Cygwin support.
|
||||
|
||||
o Created the extensions directory.
|
||||
|
||||
o Fixed warnings from ia64asm.S.
|
||||
|
||||
|
||||
Changes from 1.2 to 1.3.
|
||||
------------------------
|
||||
o Added st_read_resid() and st_write_resid() to allow the caller to know
|
||||
how much data was transferred before an error occurred. Updated
|
||||
documentation.
|
||||
|
||||
o Updated project link, copyrights, and documentation regarding
|
||||
timeouts. Added comment to st_connect().
|
||||
|
||||
o Optimized the _st_add_sleep_q() function in sched.c. Now we walk the
|
||||
sleep queue *backward* when inserting a thread into it. When you
|
||||
have lots (hundreds) of threads and several timeout values, it takes
|
||||
a while to insert a thread at the appropriate point in the sleep
|
||||
queue. The idea is that often this appropriate point is closer to
|
||||
the end of the queue rather than the beginning. Measurements show
|
||||
performance improves with this change. In any case this change
|
||||
should do no harm.
|
||||
|
||||
o Added a hint of when to define USE_POLL and when not to, to the
|
||||
Makefile.
|
||||
|
||||
o Added debugging support (files common.h and sched.c). See above.
|
||||
|
||||
o Decreased the number of reallocations of _ST_POLLFDS in sched.c.
|
||||
Inspired by Lev Walkin.
|
||||
|
||||
o Fixed st_usleep(-1) and st_sleep(-1), and added a warning to the
|
||||
documentation about too-large timeouts.
|
||||
|
||||
o Linux/*BSD Alpha port.
|
||||
|
||||
o Wesley W. Terpstra modernized the build process:
|
||||
- properly build relocatable libraries under bsd and linux
|
||||
- use library versioning
|
||||
- added rpm spec file
|
||||
- added debian/ files
|
||||
See above for build instructions.
|
||||
|
||||
|
||||
Changes from 1.1 to 1.2.
|
||||
------------------------
|
||||
o Added st_randomize_stacks().
|
||||
|
||||
o Added a patch contributed by Sascha Schumann.
|
||||
|
||||
|
||||
Changes from 1.0 to 1.1.
|
||||
------------------------
|
||||
o Relicensed under dual MPL-GPL.
|
||||
|
||||
o OpenBSD port.
|
||||
|
||||
o Compile-time option to use poll() instead of select() for
|
||||
event polling (see Makefile).
|
||||
This is useful if you want to support a large number of open
|
||||
file descriptors (larger than FD_SETSIZE) within a single
|
||||
process.
|
||||
|
||||
o Linux IA-64 port.
|
||||
Two issues make IA-64 different from other platforms:
|
||||
|
||||
- Besides the traditional call stack in memory, IA-64 uses the
|
||||
general register stack. Thus each thread needs a backing store
|
||||
for the register stack in addition to the memory stack.
|
||||
|
||||
- Current implementation of setjmp()/longjmp() can not be used
|
||||
for thread context-switching since it assumes that only one
|
||||
register stack exists. Using special assembly functions for
|
||||
context-switching is unavoidable.
|
||||
|
||||
o Thread stack capping on IRIX.
|
||||
This allows some profiling tools (such as SpeedShop) to know when
|
||||
to stop unwinding the stack. Without this libexc, used by SpeedShop,
|
||||
traces right off the stack and crashes.
|
||||
|
||||
o Miscellaneous documentation additions.
|
||||
|
||||
|
||||
COPYRIGHTS
|
||||
|
||||
Portions created by SGI are Copyright (C) 2000 Silicon Graphics, Inc.
|
||||
All Rights Reserved.
|
88
trunk/3rdparty/st-srs/README.md
vendored
Normal file
88
trunk/3rdparty/st-srs/README.md
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
# state-threads
|
||||
|
||||
![](http://ossrs.net:8000/gif/v1/sls.gif?site=github.com&path=/srs/srsst)
|
||||
[![](https://cloud.githubusercontent.com/assets/2777660/22814959/c51cbe72-ef92-11e6-81cc-32b657b285d5.png)](https://github.com/ossrs/srs/wiki/v1_CN_Contact#wechat)
|
||||
|
||||
Fork from http://sourceforge.net/projects/state-threads, patched for [SRS](https://github.com/ossrs/srs/tree/2.0release).
|
||||
|
||||
> See: https://github.com/ossrs/state-threads/blob/srs/README
|
||||
|
||||
For original ST without any changes, checkout the [ST master branch](https://github.com/ossrs/state-threads/tree/master).
|
||||
|
||||
## Branch SRS
|
||||
|
||||
The branch [srs](https://github.com/ossrs/state-threads/tree/srs) will be patched the following patches:
|
||||
|
||||
- [x] Patch [st.arm.patch](https://github.com/ossrs/srs/blob/2.0release/trunk/3rdparty/patches/1.st.arm.patch), for ARM.
|
||||
- [x] Patch [st.osx.kqueue.patch](https://github.com/ossrs/srs/blob/2.0release/trunk/3rdparty/patches/3.st.osx.kqueue.patch), for osx.
|
||||
- [x] Patch [st.disable.examples.patch](https://github.com/ossrs/srs/blob/2.0release/trunk/3rdparty/patches/4.st.disable.examples.patch), for ubuntu.
|
||||
- [x] [Refine TAB of code](https://github.com/ossrs/state-threads/compare/c2001d30ca58f55d72a6cc6b9b6c70391eaf14db...d2101b26988b0e0db0aabc53ddf452068c1e2cbc).
|
||||
- [x] Merge from [michaeltalyansky](https://github.com/michaeltalyansky/state-threads) and [xzh3836598](https://github.com/ossrs/state-threads/commit/9a17dec8f9c2814d93761665df7c5575a4d2d8a3), support [ARM](https://github.com/ossrs/state-threads/issues/1).
|
||||
- [x] Merge from [toffaletti](https://github.com/toffaletti/state-threads), support [valgrind](https://github.com/ossrs/state-threads/issues/2) for ST.
|
||||
- [x] Patch [st.osx10.14.build.patch](https://github.com/ossrs/srs/blob/2.0release/trunk/3rdparty/patches/6.st.osx10.14.build.patch), for osx 10.14 build.
|
||||
- [x] Support macro `MD_ST_NO_ASM` to disable ASM, [#8](https://github.com/ossrs/state-threads/issues/8).
|
||||
- [x] Merge patch [srs#1282](https://github.com/ossrs/srs/issues/1282#issuecomment-445539513) to support aarch64, [#9](https://github.com/ossrs/state-threads/issues/9).
|
||||
|
||||
## Docs
|
||||
|
||||
* Introduction: http://ossrs.github.io/state-threads/docs/st.html
|
||||
* API reference: http://ossrs.github.io/state-threads/docs/reference.html
|
||||
* Programming notes: http://ossrs.github.io/state-threads/docs/notes.html
|
||||
|
||||
## Usage
|
||||
|
||||
Get code:
|
||||
|
||||
```
|
||||
git clone https://github.com/ossrs/state-threads.git st-1.9 &&
|
||||
git checkout -b srs origin/srs
|
||||
```
|
||||
|
||||
For Linux:
|
||||
|
||||
```
|
||||
make linux-debug EXTRA_CFLAGS="-DMD_HAVE_EPOLL"
|
||||
```
|
||||
|
||||
For OSX:
|
||||
|
||||
```
|
||||
make darwin-debug EXTRA_CFLAGS="-DMD_HAVE_KQUEUE"
|
||||
```
|
||||
|
||||
Linux with valgrind:
|
||||
|
||||
```
|
||||
make linux-debug EXTRA_CFLAGS="-DMD_VALGRIND"
|
||||
```
|
||||
|
||||
> Remark: User must install valgrind, for instance, in centos6 `sudo yum install -y valgrind valgrind-devel`.
|
||||
|
||||
Linux with valgrind and epoll:
|
||||
|
||||
```
|
||||
make linux-debug EXTRA_CFLAGS="-DMD_HAVE_EPOLL -DMD_VALGRIND"
|
||||
```
|
||||
|
||||
For OSX, user must specifies the valgrind header files:
|
||||
|
||||
```
|
||||
make darwin-debug EXTRA_CFLAGS="-DMD_HAVE_KQUEUE -DMD_VALGRIND -I/usr/local/include"
|
||||
```
|
||||
|
||||
> Remark: Latest OSX does not support ST, please use docker to run ST.
|
||||
|
||||
## Valgrind
|
||||
|
||||
How to debug with gdb under valgrind, read [valgrind manual](http://valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.gdbserver-simple).
|
||||
|
||||
About startup parameters, read [valgrind cli](http://valgrind.org/docs/manual/mc-manual.html#mc-manual.options).
|
||||
|
||||
Important cli options:
|
||||
|
||||
1. `--undef-value-errors=<yes|no> [default: yes]`, Controls whether Memcheck reports uses of undefined value errors. Set this to no if you don't want to see undefined value errors. It also has the side effect of speeding up Memcheck somewhat.
|
||||
1. `--leak-check=<no|summary|yes|full> [default: summary]`, When enabled, search for memory leaks when the client program finishes. If set to summary, it says how many leaks occurred. If set to full or yes, each individual leak will be shown in detail and/or counted as an error, as specified by the options `--show-leak-kinds` and `--errors-for-leak-kinds`.
|
||||
1. `--track-origins=<yes|no> [default: no]`, Controls whether Memcheck tracks the origin of uninitialised values. By default, it does not, which means that although it can tell you that an uninitialised value is being used in a dangerous way, it cannot tell you where the uninitialised value came from. This often makes it difficult to track down the root problem.
|
||||
1. `--show-reachable=<yes|no> , --show-possibly-lost=<yes|no>`, to show the using memory.
|
||||
|
||||
Winlin 2016
|
479
trunk/3rdparty/st-srs/common.h
vendored
Normal file
479
trunk/3rdparty/st-srs/common.h
vendored
Normal file
|
@ -0,0 +1,479 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape Portable Runtime library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Silicon Graphics, Inc.
|
||||
*
|
||||
* Portions created by SGI are Copyright (C) 2000-2001 Silicon
|
||||
* Graphics, Inc. All Rights Reserved.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is derived directly from Netscape Communications Corporation,
|
||||
* and consists of extensive modifications made during the year(s) 1999-2000.
|
||||
*/
|
||||
|
||||
#ifndef __ST_COMMON_H__
|
||||
#define __ST_COMMON_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
/* Enable assertions only if DEBUG is defined */
|
||||
#ifndef DEBUG
|
||||
#define NDEBUG
|
||||
#endif
|
||||
#include <assert.h>
|
||||
#define ST_ASSERT(expr) assert(expr)
|
||||
|
||||
#define ST_BEGIN_MACRO {
|
||||
#define ST_END_MACRO }
|
||||
|
||||
#ifdef DEBUG
|
||||
#define ST_HIDDEN /*nothing*/
|
||||
#else
|
||||
#define ST_HIDDEN static
|
||||
#endif
|
||||
|
||||
#include "public.h"
|
||||
#include "md.h"
|
||||
|
||||
/* merge from https://github.com/toffaletti/state-threads/commit/7f57fc9acc05e657bca1223f1e5b9b1a45ed929b */
|
||||
#ifndef MD_VALGRIND
|
||||
#ifndef NVALGRIND
|
||||
#define NVALGRIND
|
||||
#endif
|
||||
#else
|
||||
#undef NVALGRIND
|
||||
#endif
|
||||
|
||||
|
||||
/*****************************************
|
||||
* Circular linked list definitions
|
||||
*/
|
||||
|
||||
typedef struct _st_clist {
|
||||
struct _st_clist *next;
|
||||
struct _st_clist *prev;
|
||||
} _st_clist_t;
|
||||
|
||||
/* Insert element "_e" into the list, before "_l" */
|
||||
#define ST_INSERT_BEFORE(_e,_l) \
|
||||
ST_BEGIN_MACRO \
|
||||
(_e)->next = (_l); \
|
||||
(_e)->prev = (_l)->prev; \
|
||||
(_l)->prev->next = (_e); \
|
||||
(_l)->prev = (_e); \
|
||||
ST_END_MACRO
|
||||
|
||||
/* Insert element "_e" into the list, after "_l" */
|
||||
#define ST_INSERT_AFTER(_e,_l) \
|
||||
ST_BEGIN_MACRO \
|
||||
(_e)->next = (_l)->next; \
|
||||
(_e)->prev = (_l); \
|
||||
(_l)->next->prev = (_e); \
|
||||
(_l)->next = (_e); \
|
||||
ST_END_MACRO
|
||||
|
||||
/* Return the element following element "_e" */
|
||||
#define ST_NEXT_LINK(_e) ((_e)->next)
|
||||
|
||||
/* Append an element "_e" to the end of the list "_l" */
|
||||
#define ST_APPEND_LINK(_e,_l) ST_INSERT_BEFORE(_e,_l)
|
||||
|
||||
/* Insert an element "_e" at the head of the list "_l" */
|
||||
#define ST_INSERT_LINK(_e,_l) ST_INSERT_AFTER(_e,_l)
|
||||
|
||||
/* Return the head/tail of the list */
|
||||
#define ST_LIST_HEAD(_l) (_l)->next
|
||||
#define ST_LIST_TAIL(_l) (_l)->prev
|
||||
|
||||
/* Remove the element "_e" from it's circular list */
|
||||
#define ST_REMOVE_LINK(_e) \
|
||||
ST_BEGIN_MACRO \
|
||||
(_e)->prev->next = (_e)->next; \
|
||||
(_e)->next->prev = (_e)->prev; \
|
||||
ST_END_MACRO
|
||||
|
||||
/* Return non-zero if the given circular list "_l" is empty, */
|
||||
/* zero if the circular list is not empty */
|
||||
#define ST_CLIST_IS_EMPTY(_l) \
|
||||
((_l)->next == (_l))
|
||||
|
||||
/* Initialize a circular list */
|
||||
#define ST_INIT_CLIST(_l) \
|
||||
ST_BEGIN_MACRO \
|
||||
(_l)->next = (_l); \
|
||||
(_l)->prev = (_l); \
|
||||
ST_END_MACRO
|
||||
|
||||
#define ST_INIT_STATIC_CLIST(_l) \
|
||||
{(_l), (_l)}
|
||||
|
||||
|
||||
/*****************************************
|
||||
* Basic types definitions
|
||||
*/
|
||||
|
||||
typedef void (*_st_destructor_t)(void *);
|
||||
|
||||
|
||||
typedef struct _st_stack {
|
||||
_st_clist_t links;
|
||||
char *vaddr; /* Base of stack's allocated memory */
|
||||
int vaddr_size; /* Size of stack's allocated memory */
|
||||
int stk_size; /* Size of usable portion of the stack */
|
||||
char *stk_bottom; /* Lowest address of stack's usable portion */
|
||||
char *stk_top; /* Highest address of stack's usable portion */
|
||||
void *sp; /* Stack pointer from C's point of view */
|
||||
#ifdef __ia64__
|
||||
void *bsp; /* Register stack backing store pointer */
|
||||
#endif
|
||||
/* merge from https://github.com/toffaletti/state-threads/commit/7f57fc9acc05e657bca1223f1e5b9b1a45ed929b */
|
||||
#ifndef NVALGRIND
|
||||
/* id returned by VALGRIND_STACK_REGISTER */
|
||||
/* http://valgrind.org/docs/manual/manual-core-adv.html */
|
||||
unsigned long valgrind_stack_id;
|
||||
#endif
|
||||
} _st_stack_t;
|
||||
|
||||
|
||||
typedef struct _st_cond {
|
||||
_st_clist_t wait_q; /* Condition variable wait queue */
|
||||
} _st_cond_t;
|
||||
|
||||
|
||||
typedef struct _st_thread _st_thread_t;
|
||||
|
||||
struct _st_thread {
|
||||
int state; /* Thread's state */
|
||||
int flags; /* Thread's flags */
|
||||
|
||||
void *(*start)(void *arg); /* The start function of the thread */
|
||||
void *arg; /* Argument of the start function */
|
||||
void *retval; /* Return value of the start function */
|
||||
|
||||
_st_stack_t *stack; /* Info about thread's stack */
|
||||
|
||||
_st_clist_t links; /* For putting on run/sleep/zombie queue */
|
||||
_st_clist_t wait_links; /* For putting on mutex/condvar wait queue */
|
||||
#ifdef DEBUG
|
||||
_st_clist_t tlink; /* For putting on thread queue */
|
||||
#endif
|
||||
|
||||
st_utime_t due; /* Wakeup time when thread is sleeping */
|
||||
_st_thread_t *left; /* For putting in timeout heap */
|
||||
_st_thread_t *right; /* -- see docs/timeout_heap.txt for details */
|
||||
int heap_index;
|
||||
|
||||
void **private_data; /* Per thread private data */
|
||||
|
||||
_st_cond_t *term; /* Termination condition variable for join */
|
||||
|
||||
jmp_buf context; /* Thread's context */
|
||||
};
|
||||
|
||||
|
||||
typedef struct _st_mutex {
|
||||
_st_thread_t *owner; /* Current mutex owner */
|
||||
_st_clist_t wait_q; /* Mutex wait queue */
|
||||
} _st_mutex_t;
|
||||
|
||||
|
||||
typedef struct _st_pollq {
|
||||
_st_clist_t links; /* For putting on io queue */
|
||||
_st_thread_t *thread; /* Polling thread */
|
||||
struct pollfd *pds; /* Array of poll descriptors */
|
||||
int npds; /* Length of the array */
|
||||
int on_ioq; /* Is it on ioq? */
|
||||
} _st_pollq_t;
|
||||
|
||||
|
||||
typedef struct _st_eventsys_ops {
|
||||
const char *name; /* Name of this event system */
|
||||
int val; /* Type of this event system */
|
||||
int (*init)(void); /* Initialization */
|
||||
void (*dispatch)(void); /* Dispatch function */
|
||||
int (*pollset_add)(struct pollfd *, int); /* Add descriptor set */
|
||||
void (*pollset_del)(struct pollfd *, int); /* Delete descriptor set */
|
||||
int (*fd_new)(int); /* New descriptor allocated */
|
||||
int (*fd_close)(int); /* Descriptor closed */
|
||||
int (*fd_getlimit)(void); /* Descriptor hard limit */
|
||||
} _st_eventsys_t;
|
||||
|
||||
|
||||
typedef struct _st_vp {
|
||||
_st_thread_t *idle_thread; /* Idle thread for this vp */
|
||||
st_utime_t last_clock; /* The last time we went into vp_check_clock() */
|
||||
|
||||
_st_clist_t run_q; /* run queue for this vp */
|
||||
_st_clist_t io_q; /* io queue for this vp */
|
||||
_st_clist_t zombie_q; /* zombie queue for this vp */
|
||||
#ifdef DEBUG
|
||||
_st_clist_t thread_q; /* all threads of this vp */
|
||||
#endif
|
||||
int pagesize;
|
||||
|
||||
_st_thread_t *sleep_q; /* sleep queue for this vp */
|
||||
int sleepq_size; /* number of threads on sleep queue */
|
||||
|
||||
#ifdef ST_SWITCH_CB
|
||||
st_switch_cb_t switch_out_cb; /* called when a thread is switched out */
|
||||
st_switch_cb_t switch_in_cb; /* called when a thread is switched in */
|
||||
#endif
|
||||
} _st_vp_t;
|
||||
|
||||
|
||||
typedef struct _st_netfd {
|
||||
int osfd; /* Underlying OS file descriptor */
|
||||
int inuse; /* In-use flag */
|
||||
void *private_data; /* Per descriptor private data */
|
||||
_st_destructor_t destructor; /* Private data destructor function */
|
||||
void *aux_data; /* Auxiliary data for internal use */
|
||||
struct _st_netfd *next; /* For putting on the free list */
|
||||
} _st_netfd_t;
|
||||
|
||||
|
||||
/*****************************************
|
||||
* Current vp, thread, and event system
|
||||
*/
|
||||
|
||||
extern _st_vp_t _st_this_vp;
|
||||
extern _st_thread_t *_st_this_thread;
|
||||
extern _st_eventsys_t *_st_eventsys;
|
||||
|
||||
#define _ST_CURRENT_THREAD() (_st_this_thread)
|
||||
#define _ST_SET_CURRENT_THREAD(_thread) (_st_this_thread = (_thread))
|
||||
|
||||
#define _ST_LAST_CLOCK (_st_this_vp.last_clock)
|
||||
|
||||
#define _ST_RUNQ (_st_this_vp.run_q)
|
||||
#define _ST_IOQ (_st_this_vp.io_q)
|
||||
#define _ST_ZOMBIEQ (_st_this_vp.zombie_q)
|
||||
#ifdef DEBUG
|
||||
#define _ST_THREADQ (_st_this_vp.thread_q)
|
||||
#endif
|
||||
|
||||
#define _ST_PAGE_SIZE (_st_this_vp.pagesize)
|
||||
|
||||
#define _ST_SLEEPQ (_st_this_vp.sleep_q)
|
||||
#define _ST_SLEEPQ_SIZE (_st_this_vp.sleepq_size)
|
||||
|
||||
#define _ST_VP_IDLE() (*_st_eventsys->dispatch)()
|
||||
|
||||
|
||||
/*****************************************
|
||||
* vp queues operations
|
||||
*/
|
||||
|
||||
#define _ST_ADD_IOQ(_pq) ST_APPEND_LINK(&_pq.links, &_ST_IOQ)
|
||||
#define _ST_DEL_IOQ(_pq) ST_REMOVE_LINK(&_pq.links)
|
||||
|
||||
#define _ST_ADD_RUNQ(_thr) ST_APPEND_LINK(&(_thr)->links, &_ST_RUNQ)
|
||||
#define _ST_DEL_RUNQ(_thr) ST_REMOVE_LINK(&(_thr)->links)
|
||||
|
||||
#define _ST_ADD_SLEEPQ(_thr, _timeout) _st_add_sleep_q(_thr, _timeout)
|
||||
#define _ST_DEL_SLEEPQ(_thr) _st_del_sleep_q(_thr)
|
||||
|
||||
#define _ST_ADD_ZOMBIEQ(_thr) ST_APPEND_LINK(&(_thr)->links, &_ST_ZOMBIEQ)
|
||||
#define _ST_DEL_ZOMBIEQ(_thr) ST_REMOVE_LINK(&(_thr)->links)
|
||||
|
||||
#ifdef DEBUG
|
||||
#define _ST_ADD_THREADQ(_thr) ST_APPEND_LINK(&(_thr)->tlink, &_ST_THREADQ)
|
||||
#define _ST_DEL_THREADQ(_thr) ST_REMOVE_LINK(&(_thr)->tlink)
|
||||
#endif
|
||||
|
||||
|
||||
/*****************************************
|
||||
* Thread states and flags
|
||||
*/
|
||||
|
||||
#define _ST_ST_RUNNING 0
|
||||
#define _ST_ST_RUNNABLE 1
|
||||
#define _ST_ST_IO_WAIT 2
|
||||
#define _ST_ST_LOCK_WAIT 3
|
||||
#define _ST_ST_COND_WAIT 4
|
||||
#define _ST_ST_SLEEPING 5
|
||||
#define _ST_ST_ZOMBIE 6
|
||||
#define _ST_ST_SUSPENDED 7
|
||||
|
||||
#define _ST_FL_PRIMORDIAL 0x01
|
||||
#define _ST_FL_IDLE_THREAD 0x02
|
||||
#define _ST_FL_ON_SLEEPQ 0x04
|
||||
#define _ST_FL_INTERRUPT 0x08
|
||||
#define _ST_FL_TIMEDOUT 0x10
|
||||
|
||||
|
||||
/*****************************************
|
||||
* Pointer conversion
|
||||
*/
|
||||
|
||||
#ifndef offsetof
|
||||
#define offsetof(type, identifier) ((size_t)&(((type *)0)->identifier))
|
||||
#endif
|
||||
|
||||
#define _ST_THREAD_PTR(_qp) \
|
||||
((_st_thread_t *)((char *)(_qp) - offsetof(_st_thread_t, links)))
|
||||
|
||||
#define _ST_THREAD_WAITQ_PTR(_qp) \
|
||||
((_st_thread_t *)((char *)(_qp) - offsetof(_st_thread_t, wait_links)))
|
||||
|
||||
#define _ST_THREAD_STACK_PTR(_qp) \
|
||||
((_st_stack_t *)((char*)(_qp) - offsetof(_st_stack_t, links)))
|
||||
|
||||
#define _ST_POLLQUEUE_PTR(_qp) \
|
||||
((_st_pollq_t *)((char *)(_qp) - offsetof(_st_pollq_t, links)))
|
||||
|
||||
#ifdef DEBUG
|
||||
#define _ST_THREAD_THREADQ_PTR(_qp) \
|
||||
((_st_thread_t *)((char *)(_qp) - offsetof(_st_thread_t, tlink)))
|
||||
#endif
|
||||
|
||||
|
||||
/*****************************************
|
||||
* Constants
|
||||
*/
|
||||
|
||||
#ifndef ST_UTIME_NO_TIMEOUT
|
||||
#define ST_UTIME_NO_TIMEOUT ((st_utime_t) -1LL)
|
||||
#endif
|
||||
|
||||
#ifndef __ia64__
|
||||
#define ST_DEFAULT_STACK_SIZE (64*1024)
|
||||
#else
|
||||
#define ST_DEFAULT_STACK_SIZE (128*1024) /* Includes register stack size */
|
||||
#endif
|
||||
|
||||
#ifndef ST_KEYS_MAX
|
||||
#define ST_KEYS_MAX 16
|
||||
#endif
|
||||
|
||||
#ifndef ST_MIN_POLLFDS_SIZE
|
||||
#define ST_MIN_POLLFDS_SIZE 64
|
||||
#endif
|
||||
|
||||
|
||||
/*****************************************
|
||||
* Threads context switching
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
void _st_iterate_threads(void);
|
||||
#define ST_DEBUG_ITERATE_THREADS() _st_iterate_threads()
|
||||
#else
|
||||
#define ST_DEBUG_ITERATE_THREADS()
|
||||
#endif
|
||||
|
||||
#ifdef ST_SWITCH_CB
|
||||
#define ST_SWITCH_OUT_CB(_thread) \
|
||||
if (_st_this_vp.switch_out_cb != NULL && \
|
||||
_thread != _st_this_vp.idle_thread && \
|
||||
_thread->state != _ST_ST_ZOMBIE) { \
|
||||
_st_this_vp.switch_out_cb(); \
|
||||
}
|
||||
#define ST_SWITCH_IN_CB(_thread) \
|
||||
if (_st_this_vp.switch_in_cb != NULL && \
|
||||
_thread != _st_this_vp.idle_thread && \
|
||||
_thread->state != _ST_ST_ZOMBIE) { \
|
||||
_st_this_vp.switch_in_cb(); \
|
||||
}
|
||||
#else
|
||||
#define ST_SWITCH_OUT_CB(_thread)
|
||||
#define ST_SWITCH_IN_CB(_thread)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Switch away from the current thread context by saving its state and
|
||||
* calling the thread scheduler
|
||||
*/
|
||||
#define _ST_SWITCH_CONTEXT(_thread) \
|
||||
ST_BEGIN_MACRO \
|
||||
ST_SWITCH_OUT_CB(_thread); \
|
||||
if (!MD_SETJMP((_thread)->context)) { \
|
||||
_st_vp_schedule(); \
|
||||
} \
|
||||
ST_DEBUG_ITERATE_THREADS(); \
|
||||
ST_SWITCH_IN_CB(_thread); \
|
||||
ST_END_MACRO
|
||||
|
||||
/*
|
||||
* Restore a thread context that was saved by _ST_SWITCH_CONTEXT or
|
||||
* initialized by _ST_INIT_CONTEXT
|
||||
*/
|
||||
#define _ST_RESTORE_CONTEXT(_thread) \
|
||||
ST_BEGIN_MACRO \
|
||||
_ST_SET_CURRENT_THREAD(_thread); \
|
||||
MD_LONGJMP((_thread)->context, 1); \
|
||||
ST_END_MACRO
|
||||
|
||||
/*
|
||||
* Initialize the thread context preparing it to execute _main
|
||||
*/
|
||||
#ifdef MD_INIT_CONTEXT
|
||||
#define _ST_INIT_CONTEXT MD_INIT_CONTEXT
|
||||
#else
|
||||
#error Unknown OS
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Number of bytes reserved under the stack "bottom"
|
||||
*/
|
||||
#define _ST_STACK_PAD_SIZE MD_STACK_PAD_SIZE
|
||||
|
||||
|
||||
/*****************************************
|
||||
* Forward declarations
|
||||
*/
|
||||
|
||||
void _st_vp_schedule(void);
|
||||
void _st_vp_check_clock(void);
|
||||
void *_st_idle_thread_start(void *arg);
|
||||
void _st_thread_main(void);
|
||||
void _st_thread_cleanup(_st_thread_t *thread);
|
||||
void _st_add_sleep_q(_st_thread_t *thread, st_utime_t timeout);
|
||||
void _st_del_sleep_q(_st_thread_t *thread);
|
||||
_st_stack_t *_st_stack_new(int stack_size);
|
||||
void _st_stack_free(_st_stack_t *ts);
|
||||
int _st_io_init(void);
|
||||
|
||||
st_utime_t st_utime(void);
|
||||
_st_cond_t *st_cond_new(void);
|
||||
int st_cond_destroy(_st_cond_t *cvar);
|
||||
int st_cond_timedwait(_st_cond_t *cvar, st_utime_t timeout);
|
||||
int st_cond_signal(_st_cond_t *cvar);
|
||||
ssize_t st_read(_st_netfd_t *fd, void *buf, size_t nbyte, st_utime_t timeout);
|
||||
ssize_t st_write(_st_netfd_t *fd, const void *buf, size_t nbyte, st_utime_t timeout);
|
||||
int st_poll(struct pollfd *pds, int npds, st_utime_t timeout);
|
||||
_st_thread_t *st_thread_create(void *(*start)(void *arg), void *arg, int joinable, int stk_size);
|
||||
|
||||
#endif /* !__ST_COMMON_H__ */
|
||||
|
BIN
trunk/3rdparty/st-srs/docs/fig.gif
vendored
Normal file
BIN
trunk/3rdparty/st-srs/docs/fig.gif
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.2 KiB |
434
trunk/3rdparty/st-srs/docs/notes.html
vendored
Normal file
434
trunk/3rdparty/st-srs/docs/notes.html
vendored
Normal file
|
@ -0,0 +1,434 @@
|
|||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>State Threads Library Programming Notes</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR=#FFFFFF>
|
||||
<H2>Programming Notes</H2>
|
||||
<P>
|
||||
<B>
|
||||
<UL>
|
||||
<LI><A HREF=#porting>Porting</A></LI>
|
||||
<LI><A HREF=#signals>Signals</A></LI>
|
||||
<LI><A HREF=#intra>Intra-Process Synchronization</A></LI>
|
||||
<LI><A HREF=#inter>Inter-Process Synchronization</A></LI>
|
||||
<LI><A HREF=#nonnet>Non-Network I/O</A></LI>
|
||||
<LI><A HREF=#timeouts>Timeouts</A></LI>
|
||||
</UL>
|
||||
</B>
|
||||
<P>
|
||||
<HR>
|
||||
<P>
|
||||
<A NAME="porting">
|
||||
<H3>Porting</H3>
|
||||
The State Threads library uses OS concepts that are available in some
|
||||
form on most UNIX platforms, making the library very portable across
|
||||
many flavors of UNIX. However, there are several parts of the library
|
||||
that rely on platform-specific features. Here is the list of such parts:
|
||||
<P>
|
||||
<UL>
|
||||
<LI><I>Thread context initialization</I>: Two ingredients of the
|
||||
<TT>jmp_buf</TT>
|
||||
data structure (the program counter and the stack pointer) have to be
|
||||
manually set in the thread creation routine. The <TT>jmp_buf</TT> data
|
||||
structure is defined in the <TT>setjmp.h</TT> header file and differs from
|
||||
platform to platform. Usually the program counter is a structure member
|
||||
with <TT>PC</TT> in the name and the stack pointer is a structure member
|
||||
with <TT>SP</TT> in the name. One can also look in the
|
||||
<A HREF="http://www.mozilla.org/source.html">Netscape's NSPR library source</A>
|
||||
which already has this code for many UNIX-like platforms
|
||||
(<TT>mozilla/nsprpub/pr/include/md/*.h</TT> files).
|
||||
<P>
|
||||
Note that on some BSD-derived platforms <TT>_setjmp(3)/_longjmp(3)</TT>
|
||||
calls should be used instead of <TT>setjmp(3)/longjmp(3)</TT> (that is
|
||||
the calls that manipulate only the stack and registers and do <I>not</I>
|
||||
save and restore the process's signal mask).</LI>
|
||||
<P>
|
||||
Starting with glibc 2.4 on Linux the opacity of the <TT>jmp_buf</TT> data
|
||||
structure is enforced by <TT>setjmp(3)/longjmp(3)</TT> so the
|
||||
<TT>jmp_buf</TT> ingredients cannot be accessed directly anymore (unless
|
||||
special environmental variable LD_POINTER_GUARD is set before application
|
||||
execution). To avoid dependency on custom environment, the State Threads
|
||||
library provides <TT>setjmp/longjmp</TT> replacement functions for
|
||||
all Intel CPU architectures. Other CPU architectures can also be easily
|
||||
supported (the <TT>setjmp/longjmp</TT> source code is widely available for
|
||||
many CPU architectures).
|
||||
<P>
|
||||
<LI><I>High resolution time function</I>: Some platforms (IRIX, Solaris)
|
||||
provide a high resolution time function based on the free running hardware
|
||||
counter. This function returns the time counted since some arbitrary
|
||||
moment in the past (usually machine power up time). It is not correlated in
|
||||
any way to the time of day, and thus is not subject to resetting,
|
||||
drifting, etc. This type of time is ideal for tasks where cheap, accurate
|
||||
interval timing is required. If such a function is not available on a
|
||||
particular platform, the <TT>gettimeofday(3)</TT> function can be used
|
||||
(though on some platforms it involves a system call).
|
||||
<P>
|
||||
<LI><I>The stack growth direction</I>: The library needs to know whether the
|
||||
stack grows toward lower (down) or higher (up) memory addresses.
|
||||
One can write a simple test program that detects the stack growth direction
|
||||
on a particular platform.</LI>
|
||||
<P>
|
||||
<LI><I>Non-blocking attribute inheritance</I>: On some platforms (e.g. IRIX)
|
||||
the socket created as a result of the <TT>accept(2)</TT> call inherits the
|
||||
non-blocking attribute of the listening socket. One needs to consult the manual
|
||||
pages or write a simple test program to see if this applies to a specific
|
||||
platform.</LI>
|
||||
<P>
|
||||
<LI><I>Anonymous memory mapping</I>: The library allocates memory segments
|
||||
for thread stacks by doing anonymous memory mapping (<TT>mmap(2)</TT>). This
|
||||
mapping is somewhat different on SVR4 and BSD4.3 derived platforms.
|
||||
<P>
|
||||
The memory mapping can be avoided altogether by using <TT>malloc(3)</TT> for
|
||||
stack allocation. In this case the <TT>MALLOC_STACK</TT> macro should be
|
||||
defined.</LI>
|
||||
</UL>
|
||||
<P>
|
||||
All machine-dependent feature test macros should be defined in the
|
||||
<TT>md.h</TT> header file. The assembly code for <TT>setjmp/longjmp</TT>
|
||||
replacement functions for all CPU architectures should be placed in
|
||||
the <TT>md.S</TT> file.
|
||||
<P>
|
||||
The current version of the library is ported to:
|
||||
<UL>
|
||||
<LI>IRIX 6.x (both 32 and 64 bit)</LI>
|
||||
<LI>Linux (kernel 2.x and glibc 2.x) on x86, Alpha, MIPS and MIPSEL,
|
||||
SPARC, ARM, PowerPC, 68k, HPPA, S390, IA-64, and Opteron (AMD-64)</LI>
|
||||
<LI>Solaris 2.x (SunOS 5.x) on x86, AMD64, SPARC, and SPARC-64</LI>
|
||||
<LI>AIX 4.x</LI>
|
||||
<LI>HP-UX 11 (both 32 and 64 bit)</LI>
|
||||
<LI>Tru64/OSF1</LI>
|
||||
<LI>FreeBSD on x86, AMD64, and Alpha</LI>
|
||||
<LI>OpenBSD on x86, AMD64, Alpha, and SPARC</LI>
|
||||
<LI>NetBSD on x86, Alpha, SPARC, and VAX</LI>
|
||||
<LI>MacOS X (Darwin) on PowerPC (32 bit) and Intel (both 32 and 64 bit) [universal]</LI>
|
||||
<LI>Cygwin</LI>
|
||||
</UL>
|
||||
<P>
|
||||
|
||||
<A NAME="signals">
|
||||
<H3>Signals</H3>
|
||||
Signal handling in an application using State Threads should be treated the
|
||||
same way as in a classical UNIX process application. There is no such
|
||||
thing as per-thread signal mask, all threads share the same signal handlers,
|
||||
and only asynchronous-safe functions can be used in signal handlers.
|
||||
However, there is a way to process signals synchronously by converting a
|
||||
signal event to an I/O event: a signal catching function does a write to
|
||||
a pipe which will be processed synchronously by a dedicated signal handling
|
||||
thread. The following code demonstrates this technique (error handling is
|
||||
omitted for clarity):
|
||||
<PRE>
|
||||
|
||||
/* Per-process pipe which is used as a signal queue. */
|
||||
/* Up to PIPE_BUF/sizeof(int) signals can be queued up. */
|
||||
int sig_pipe[2];
|
||||
|
||||
/* Signal catching function. */
|
||||
/* Converts signal event to I/O event. */
|
||||
void sig_catcher(int signo)
|
||||
{
|
||||
int err;
|
||||
|
||||
/* Save errno to restore it after the write() */
|
||||
err = errno;
|
||||
/* write() is reentrant/async-safe */
|
||||
write(sig_pipe[1], &signo, sizeof(int));
|
||||
errno = err;
|
||||
}
|
||||
|
||||
/* Signal processing function. */
|
||||
/* This is the "main" function of the signal processing thread. */
|
||||
void *sig_process(void *arg)
|
||||
{
|
||||
st_netfd_t nfd;
|
||||
int signo;
|
||||
|
||||
nfd = st_netfd_open(sig_pipe[0]);
|
||||
|
||||
for ( ; ; ) {
|
||||
/* Read the next signal from the pipe */
|
||||
st_read(nfd, &signo, sizeof(int), ST_UTIME_NO_TIMEOUT);
|
||||
|
||||
/* Process signal synchronously */
|
||||
switch (signo) {
|
||||
case SIGHUP:
|
||||
/* do something here - reread config files, etc. */
|
||||
break;
|
||||
case SIGTERM:
|
||||
/* do something here - cleanup, etc. */
|
||||
break;
|
||||
/* .
|
||||
.
|
||||
Other signals
|
||||
.
|
||||
.
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct sigaction sa;
|
||||
.
|
||||
.
|
||||
.
|
||||
|
||||
/* Create signal pipe */
|
||||
pipe(sig_pipe);
|
||||
|
||||
/* Create signal processing thread */
|
||||
st_thread_create(sig_process, NULL, 0, 0);
|
||||
|
||||
/* Install sig_catcher() as a signal handler */
|
||||
sa.sa_handler = sig_catcher;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = 0;
|
||||
sigaction(SIGHUP, &sa, NULL);
|
||||
|
||||
sa.sa_handler = sig_catcher;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = 0;
|
||||
sigaction(SIGTERM, &sa, NULL);
|
||||
|
||||
.
|
||||
.
|
||||
.
|
||||
|
||||
}
|
||||
|
||||
</PRE>
|
||||
<P>
|
||||
Note that if multiple processes are used (see below), the signal pipe should
|
||||
be initialized after the <TT>fork(2)</TT> call so that each process has its
|
||||
own private pipe.
|
||||
<P>
|
||||
|
||||
<A NAME="intra">
|
||||
<H3>Intra-Process Synchronization</H3>
|
||||
Due to the event-driven nature of the library scheduler, the thread context
|
||||
switch (process state change) can only happen in a well-known set of
|
||||
library functions. This set includes functions in which a thread may
|
||||
"block":<TT> </TT>I/O functions (<TT>st_read(), st_write(), </TT>etc.),
|
||||
sleep functions (<TT>st_sleep(), </TT>etc.), and thread synchronization
|
||||
functions (<TT>st_thread_join(), st_cond_wait(), </TT>etc.). As a result,
|
||||
process-specific global data need not to be protected by locks since a thread
|
||||
cannot be rescheduled while in a critical section (and only one thread at a
|
||||
time can access the same memory location). By the same token,
|
||||
non thread-safe functions (in a traditional sense) can be safely used with
|
||||
the State Threads. The library's mutex facilities are practically useless
|
||||
for a correctly written application (no blocking functions in critical
|
||||
section) and are provided mostly for completeness. This absence of locking
|
||||
greatly simplifies an application design and provides a foundation for
|
||||
scalability.
|
||||
<P>
|
||||
|
||||
<A NAME="inter">
|
||||
<H3>Inter-Process Synchronization</H3>
|
||||
The State Threads library makes it possible to multiplex a large number
|
||||
of simultaneous connections onto a much smaller number of separate
|
||||
processes, where each process uses a many-to-one user-level threading
|
||||
implementation (<B>N</B> of <B>M:1</B> mappings rather than one <B>M:N</B>
|
||||
mapping used in native threading libraries on some platforms). This design
|
||||
is key to the application's scalability. One can think about it as if a
|
||||
set of all threads is partitioned into separate groups (processes) where
|
||||
each group has a separate pool of resources (virtual address space, file
|
||||
descriptors, etc.). An application designer has full control of how many
|
||||
groups (processes) an application creates and what resources, if any,
|
||||
are shared among different groups via standard UNIX inter-process
|
||||
communication (IPC) facilities.<P>
|
||||
There are several reasons for creating multiple processes:
|
||||
<P>
|
||||
<UL>
|
||||
<LI>To take advantage of multiple hardware entities (CPUs, disks, etc.)
|
||||
available in the system (hardware parallelism).</LI>
|
||||
<P>
|
||||
<LI>To reduce risk of losing a large number of user connections when one of
|
||||
the processes crashes. For example, if <B>C</B> user connections (threads)
|
||||
are multiplexed onto <B>P</B> processes and one of the processes crashes,
|
||||
only a fraction (<B>C/P</B>) of all connections will be lost.</LI>
|
||||
<P>
|
||||
<LI>To overcome per-process resource limitations imposed by the OS. For
|
||||
example, if <TT>select(2)</TT> is used for event polling, the number of
|
||||
simultaneous connections (threads) per process is
|
||||
limited by the <TT>FD_SETSIZE</TT> parameter (see <TT>select(2)</TT>).
|
||||
If <TT>FD_SETSIZE</TT> is equal to 1024 and each connection needs one file
|
||||
descriptor, then an application should create 10 processes to support 10,000
|
||||
simultaneous connections.</LI>
|
||||
</UL>
|
||||
<P>
|
||||
Ideally all user sessions are completely independent, so there is no need for
|
||||
inter-process communication. It is always better to have several separate
|
||||
smaller process-specific resources (e.g., data caches) than to have one large
|
||||
resource shared (and modified) by all processes. Sometimes, however, there
|
||||
is a need to share a common resource among different processes. In that case,
|
||||
standard UNIX IPC facilities can be used. In addition to that, there is a way
|
||||
to synchronize different processes so that only the thread accessing the
|
||||
shared resource will be suspended (but not the entire process) if that resource
|
||||
is unavailable. In the following code fragment a pipe is used as a counting
|
||||
semaphore for inter-process synchronization:
|
||||
<PRE>
|
||||
#ifndef PIPE_BUF
|
||||
#define PIPE_BUF 512 /* POSIX */
|
||||
#endif
|
||||
|
||||
/* Semaphore data structure */
|
||||
typedef struct ipc_sem {
|
||||
st_netfd_t rdfd; /* read descriptor */
|
||||
st_netfd_t wrfd; /* write descriptor */
|
||||
} ipc_sem_t;
|
||||
|
||||
/* Create and initialize the semaphore. Should be called before fork(2). */
|
||||
/* 'value' must be less than PIPE_BUF. */
|
||||
/* If 'value' is 1, the semaphore works as mutex. */
|
||||
ipc_sem_t *ipc_sem_create(int value)
|
||||
{
|
||||
ipc_sem_t *sem;
|
||||
int p[2];
|
||||
char b[PIPE_BUF];
|
||||
|
||||
/* Error checking is omitted for clarity */
|
||||
sem = malloc(sizeof(ipc_sem_t));
|
||||
|
||||
/* Create the pipe */
|
||||
pipe(p);
|
||||
sem->rdfd = st_netfd_open(p[0]);
|
||||
sem->wrfd = st_netfd_open(p[1]);
|
||||
|
||||
/* Initialize the semaphore: put 'value' bytes into the pipe */
|
||||
write(p[1], b, value);
|
||||
|
||||
return sem;
|
||||
}
|
||||
|
||||
/* Try to decrement the "value" of the semaphore. */
|
||||
/* If "value" is 0, the calling thread blocks on the semaphore. */
|
||||
int ipc_sem_wait(ipc_sem_t *sem)
|
||||
{
|
||||
char c;
|
||||
|
||||
/* Read one byte from the pipe */
|
||||
if (st_read(sem->rdfd, &c, 1, ST_UTIME_NO_TIMEOUT) != 1)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Increment the "value" of the semaphore. */
|
||||
int ipc_sem_post(ipc_sem_t *sem)
|
||||
{
|
||||
char c;
|
||||
|
||||
if (st_write(sem->wrfd, &c, 1, ST_UTIME_NO_TIMEOUT) != 1)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
</PRE>
|
||||
<P>
|
||||
|
||||
Generally, the following steps should be followed when writing an application
|
||||
using the State Threads library:
|
||||
<P>
|
||||
<OL>
|
||||
<LI>Initialize the library (<TT>st_init()</TT>).</LI>
|
||||
<P>
|
||||
<LI>Create resources that will be shared among different processes:
|
||||
create and bind listening sockets, create shared memory segments, IPC
|
||||
channels, synchronization primitives, etc.</LI>
|
||||
<P>
|
||||
<LI>Create several processes (<TT>fork(2)</TT>). The parent process should
|
||||
either exit or become a "watchdog" (e.g., it starts a new process when
|
||||
an existing one crashes, does a cleanup upon application termination,
|
||||
etc.).</LI>
|
||||
<P>
|
||||
<LI>In each child process create a pool of threads
|
||||
(<TT>st_thread_create()</TT>) to handle user connections.</LI>
|
||||
</OL>
|
||||
<P>
|
||||
|
||||
<A NAME="nonnet">
|
||||
<H3>Non-Network I/O</H3>
|
||||
|
||||
The State Threads architecture uses non-blocking I/O on
|
||||
<TT>st_netfd_t</TT> objects for concurrent processing of multiple user
|
||||
connections. This architecture has a drawback: the entire process and
|
||||
all its threads may block for the duration of a <I>disk</I> or other
|
||||
non-network I/O operation, whether through State Threads I/O functions,
|
||||
direct system calls, or standard I/O functions. (This is applicable
|
||||
mostly to disk <I>reads</I>; disk <I>writes</I> are usually performed
|
||||
asynchronously -- data goes to the buffer cache to be written to disk
|
||||
later.) Fortunately, disk I/O (unlike network I/O) usually takes a
|
||||
finite and predictable amount of time, but this may not be true for
|
||||
special devices or user input devices (including stdin). Nevertheless,
|
||||
such I/O reduces throughput of the system and increases response times.
|
||||
There are several ways to design an application to overcome this
|
||||
drawback:
|
||||
|
||||
<P>
|
||||
<UL>
|
||||
<LI>Create several identical main processes as described above (symmetric
|
||||
architecture). This will improve CPU utilization and thus improve the
|
||||
overall throughput of the system.</LI>
|
||||
<P>
|
||||
<LI>Create multiple "helper" processes in addition to the main process that
|
||||
will handle blocking I/O operations (asymmetric architecture).
|
||||
This approach was suggested for Web servers in a
|
||||
<A HREF="http://www.cs.rice.edu/~vivek/flash99/">paper</A> by Peter
|
||||
Druschel et al. In this architecture the main process communicates with
|
||||
a helper process via an IPC channel (<TT>pipe(2), socketpair(2)</TT>).
|
||||
The main process instructs a helper to perform the potentially blocking
|
||||
operation. Once the operation completes, the helper returns a
|
||||
notification via IPC.
|
||||
</UL>
|
||||
<P>
|
||||
|
||||
<A NAME="timeouts">
|
||||
<H3>Timeouts</H3>
|
||||
|
||||
The <TT>timeout</TT> parameter to <TT>st_cond_timedwait()</TT> and the
|
||||
I/O functions, and the arguments to <TT>st_sleep()</TT> and
|
||||
<TT>st_usleep()</TT> specify a maximum time to wait <I>since the last
|
||||
context switch</I> not since the beginning of the function call.
|
||||
|
||||
<P>The State Threads' time resolution is actually the time interval
|
||||
between context switches. That time interval may be large in some
|
||||
situations, for example, when a single thread does a lot of work
|
||||
continuously. Note that a steady, uninterrupted stream of network I/O
|
||||
qualifies for this description; a context switch occurs only when a
|
||||
thread blocks.
|
||||
|
||||
<P>If a specified I/O timeout is less than the time interval between
|
||||
context switches the function may return with a timeout error before
|
||||
that amount of time has elapsed since the beginning of the function
|
||||
call. For example, if eight milliseconds have passed since the last
|
||||
context switch and an I/O function with a timeout of 10 milliseconds
|
||||
blocks, causing a switch, the call may return with a timeout error as
|
||||
little as two milliseconds after it was called. (On Linux,
|
||||
<TT>select()</TT>'s timeout is an <I>upper</I> bound on the amount of
|
||||
time elapsed before select returns.) Similarly, if 12 ms have passed
|
||||
already, the function may return immediately.
|
||||
|
||||
<P>In almost all cases I/O timeouts should be used only for detecting a
|
||||
broken network connection or for preventing a peer from holding an idle
|
||||
connection for too long. Therefore for most applications realistic I/O
|
||||
timeouts should be on the order of seconds. Furthermore, there's
|
||||
probably no point in retrying operations that time out. Rather than
|
||||
retrying simply use a larger timeout in the first place.
|
||||
|
||||
<P>The largest valid timeout value is platform-dependent and may be
|
||||
significantly less than <TT>INT_MAX</TT> seconds for <TT>select()</TT>
|
||||
or <TT>INT_MAX</TT> milliseconds for <TT>poll()</TT>. Generally, you
|
||||
should not use timeouts exceeding several hours. Use
|
||||
<tt>ST_UTIME_NO_TIMEOUT</tt> (<tt>-1</tt>) as a special value to
|
||||
indicate infinite timeout or indefinite sleep. Use
|
||||
<tt>ST_UTIME_NO_WAIT</tt> (<tt>0</tt>) to indicate no waiting at all.
|
||||
|
||||
<P>
|
||||
<HR>
|
||||
<P>
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
3120
trunk/3rdparty/st-srs/docs/reference.html
vendored
Normal file
3120
trunk/3rdparty/st-srs/docs/reference.html
vendored
Normal file
File diff suppressed because it is too large
Load diff
504
trunk/3rdparty/st-srs/docs/st.html
vendored
Normal file
504
trunk/3rdparty/st-srs/docs/st.html
vendored
Normal file
|
@ -0,0 +1,504 @@
|
|||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>State Threads for Internet Applications</TITLE>
|
||||
</HEAD>
|
||||
<BODY BGCOLOR=#FFFFFF>
|
||||
<H2>State Threads for Internet Applications</H2>
|
||||
<H3>Introduction</H3>
|
||||
<P>
|
||||
State Threads is an application library which provides a
|
||||
foundation for writing fast and highly scalable Internet Applications
|
||||
on UNIX-like platforms. It combines the simplicity of the multithreaded
|
||||
programming paradigm, in which one thread supports each simultaneous
|
||||
connection, with the performance and scalability of an event-driven
|
||||
state machine architecture.</P>
|
||||
|
||||
<H3>1. Definitions</H3>
|
||||
<P>
|
||||
<A NAME="IA">
|
||||
<H4>1.1 Internet Applications</H4>
|
||||
</A>
|
||||
<P>
|
||||
An <I>Internet Application</I> (IA) is either a server or client network
|
||||
application that accepts connections from clients and may or may not
|
||||
connect to servers. In an IA the arrival or departure of network data
|
||||
often controls processing (that is, IA is a <I>data-driven</I> application).
|
||||
For each connection, an IA does some finite amount of work
|
||||
involving data exchange with its peer, where its peer may be either
|
||||
a client or a server.
|
||||
The typical transaction steps of an IA are to accept a connection,
|
||||
read a request, do some finite and predictable amount of work to
|
||||
process the request, then write a response to the peer that sent the
|
||||
request. One example of an IA is a Web server;
|
||||
the most general example of an IA is a proxy server, because it both
|
||||
accepts connections from clients and connects to other servers.</P>
|
||||
<P>
|
||||
We assume that the performance of an IA is constrained by available CPU
|
||||
cycles rather than network bandwidth or disk I/O (that is, CPU
|
||||
is a bottleneck resource).
|
||||
<P>
|
||||
|
||||
<A NAME="PS">
|
||||
<H4>1.2 Performance and Scalability</H4>
|
||||
</A>
|
||||
<P>
|
||||
The <I>performance</I> of an IA is usually evaluated as its
|
||||
throughput measured in transactions per second or bytes per second (one
|
||||
can be converted to the other, given the average transaction size). There are
|
||||
several benchmarks that can be used to measure throughput of Web serving
|
||||
applications for specific workloads (such as
|
||||
<A HREF="http://www.spec.org/osg/web96/">SPECweb96</A>,
|
||||
<A HREF="http://www.mindcraft.com/webstone/">WebStone</A>,
|
||||
<A HREF="http://www.zdnet.com/zdbop/webbench/">WebBench</A>).
|
||||
Although there is no common definition for <I>scalability</I>, in general it
|
||||
expresses the ability of an application to sustain its performance when some
|
||||
external condition changes. For IAs this external condition is either the
|
||||
number of clients (also known as "users," "simultaneous connections," or "load
|
||||
generators") or the underlying hardware system size (number of CPUs, memory
|
||||
size, and so on). Thus there are two types of scalability: <I>load
|
||||
scalability</I> and <I>system scalability</I>, respectively.
|
||||
<P>
|
||||
The figure below shows how the throughput of an idealized IA changes with
|
||||
the increasing number of clients (solid blue line). Initially the throughput
|
||||
grows linearly (the slope represents the maximal throughput that one client
|
||||
can provide). Within this initial range, the IA is underutilized and CPUs are
|
||||
partially idle. Further increase in the number of clients leads to a system
|
||||
saturation, and the throughput gradually stops growing as all CPUs become fully
|
||||
utilized. After that point, the throughput stays flat because there are no
|
||||
more CPU cycles available.
|
||||
In the real world, however, each simultaneous connection
|
||||
consumes some computational and memory resources, even when idle, and this
|
||||
overhead grows with the number of clients. Therefore, the throughput of the
|
||||
real world IA starts dropping after some point (dashed blue line in the figure
|
||||
below). The rate at which the throughput drops depends, among other things, on
|
||||
application design.
|
||||
<P>
|
||||
We say that an application has a good <I>load scalability</I> if it can
|
||||
sustain its throughput over a wide range of loads.
|
||||
Interestingly, the <A HREF="http://www.spec.org/osg/web99/">SPECweb99</A>
|
||||
benchmark somewhat reflects the Web server's load scalability because it
|
||||
measures the number of clients (load generators) given a mandatory minimal
|
||||
throughput per client (that is, it measures the server's <I>capacity</I>).
|
||||
This is unlike <A HREF="http://www.spec.org/osg/web96/">SPECweb96</A> and
|
||||
other benchmarks that use the throughput as their main metric (see the figure
|
||||
below).
|
||||
<P>
|
||||
<CENTER><IMG SRC="fig.gif" ALT="Figure: Throughput vs. Number of clients">
|
||||
</CENTER>
|
||||
<P>
|
||||
<I>System scalability</I> is the ability of an application to sustain its
|
||||
performance per hardware unit (such as a CPU) with the increasing number of
|
||||
these units. In other words, good system scalability means that doubling the
|
||||
number of processors will roughly double the application's throughput (dashed
|
||||
green line). We assume here that the underlying operating system also scales
|
||||
well. Good system scalability allows you to initially run an application on
|
||||
the smallest system possible, while retaining the ability to move that
|
||||
application to a larger system if necessary, without excessive effort or
|
||||
expense. That is, an application need not be rewritten or even undergo a
|
||||
major porting effort when changing system size.
|
||||
<P>
|
||||
Although scalability and performance are more important in the case of server
|
||||
IAs, they should also be considered for some client applications (such as
|
||||
benchmark load generators).
|
||||
<P>
|
||||
|
||||
<A NAME="CONC">
|
||||
<H4>1.3 Concurrency</H4>
|
||||
</A>
|
||||
<P>
|
||||
Concurrency reflects the parallelism in a system. The two unrelated types
|
||||
are <I>virtual</I> concurrency and <I>real</I> concurrency.
|
||||
<UL>
|
||||
<LI>Virtual (or apparent) concurrency is the number of simultaneous
|
||||
connections that a system supports.
|
||||
<BR><BR>
|
||||
<LI>Real concurrency is the number of hardware devices, including
|
||||
CPUs, network cards, and disks, that actually allow a system to perform
|
||||
tasks in parallel.
|
||||
</UL>
|
||||
<P>
|
||||
An IA must provide virtual concurrency in order to serve many users
|
||||
simultaneously.
|
||||
To achieve maximum performance and scalability in doing so, the number of
|
||||
programming entities than an IA creates to be scheduled by the OS kernel
|
||||
should be
|
||||
kept close to (within an order of magnitude of) the real concurrency found on
|
||||
the system. These programming entities scheduled by the kernel are known as
|
||||
<I>kernel execution vehicles</I>. Examples of kernel execution vehicles
|
||||
include Solaris lightweight processes and IRIX kernel threads.
|
||||
In other words, the number of kernel execution vehicles should be dictated by
|
||||
the system size and not by the number of simultaneous connections.
|
||||
<P>
|
||||
|
||||
<H3>2. Existing Architectures</H3>
|
||||
<P>
|
||||
There are a few different architectures that are commonly used by IAs.
|
||||
These include the <I>Multi-Process</I>,
|
||||
<I>Multi-Threaded</I>, and <I>Event-Driven State Machine</I>
|
||||
architectures.
|
||||
<P>
|
||||
<A NAME="MP">
|
||||
<H4>2.1 Multi-Process Architecture</H4>
|
||||
</A>
|
||||
<P>
|
||||
In the Multi-Process (MP) architecture, an individual process is
|
||||
dedicated to each simultaneous connection.
|
||||
A process performs all of a transaction's initialization steps
|
||||
and services a connection completely before moving on to service
|
||||
a new connection.
|
||||
<P>
|
||||
User sessions in IAs are relatively independent; therefore, no
|
||||
synchronization between processes handling different connections is
|
||||
necessary. Because each process has its own private address space,
|
||||
this architecture is very robust. If a process serving one of the connections
|
||||
crashes, the other sessions will not be affected. However, to serve many
|
||||
concurrent connections, an equal number of processes must be employed.
|
||||
Because processes are kernel entities (and are in fact the heaviest ones),
|
||||
the number of kernel entities will be at least as large as the number of
|
||||
concurrent sessions. On most systems, good performance will not be achieved
|
||||
when more than a few hundred processes are created because of the high
|
||||
context-switching overhead. In other words, MP applications have poor load
|
||||
scalability.
|
||||
<P>
|
||||
On the other hand, MP applications have very good system scalability, because
|
||||
no resources are shared among different processes and there is no
|
||||
synchronization overhead.
|
||||
<P>
|
||||
The Apache Web Server 1.x (<A HREF=#refs1>[Reference 1]</A>) uses the MP
|
||||
architecture on UNIX systems.
|
||||
<P>
|
||||
<A NAME="MT">
|
||||
<H4>2.2 Multi-Threaded Architecture</H4>
|
||||
</A>
|
||||
<P>
|
||||
In the Multi-Threaded (MT) architecture, multiple independent threads
|
||||
of control are employed within a single shared address space. Like a
|
||||
process in the MP architecture, each thread performs all of a
|
||||
transaction's initialization steps and services a connection completely
|
||||
before moving on to service a new connection.
|
||||
<P>
|
||||
Many modern UNIX operating systems implement a <I>many-to-few</I> model when
|
||||
mapping user-level threads to kernel entities. In this model, an
|
||||
arbitrarily large number of user-level threads is multiplexed onto a
|
||||
lesser number of kernel execution vehicles. Kernel execution
|
||||
vehicles are also known as <I>virtual processors</I>. Whenever a user-level
|
||||
thread makes a blocking system call, the kernel execution vehicle it is using
|
||||
will become blocked in the kernel. If there are no other non-blocked kernel
|
||||
execution vehicles and there are other runnable user-level threads, a new
|
||||
kernel execution vehicle will be created automatically. This prevents the
|
||||
application from blocking when it can continue to make useful forward
|
||||
progress.
|
||||
<P>
|
||||
Because IAs are by nature network I/O driven, all concurrent sessions block on
|
||||
network I/O at various points. As a result, the number of virtual processors
|
||||
created in the kernel grows close to the number of user-level threads
|
||||
(or simultaneous connections). When this occurs, the many-to-few model
|
||||
effectively degenerates to a <I>one-to-one</I> model. Again, like in
|
||||
the MP architecture, the number of kernel execution vehicles is dictated by
|
||||
the number of simultaneous connections rather than by number of CPUs. This
|
||||
reduces an application's load scalability. However, because kernel threads
|
||||
(lightweight processes) use fewer resources and are more light-weight than
|
||||
traditional UNIX processes, an MT application should scale better with load
|
||||
than an MP application.
|
||||
<P>
|
||||
Unexpectedly, the small number of virtual processors sharing the same address
|
||||
space in the MT architecture destroys an application's system scalability
|
||||
because of contention among the threads on various locks. Even if an
|
||||
application itself is carefully
|
||||
optimized to avoid lock contention around its own global data (a non-trivial
|
||||
task), there are still standard library functions and system calls
|
||||
that use common resources hidden from the application. For example,
|
||||
on many platforms thread safety of memory allocation routines
|
||||
(<TT>malloc(3)</TT>, <TT>free(3)</TT>, and so on) is achieved by using a single
|
||||
global lock. Another example is a per-process file descriptor table.
|
||||
This common resource table is shared by all kernel execution vehicles within
|
||||
the same process and must be protected when one modifies it via
|
||||
certain system calls (such as <TT>open(2)</TT>, <TT>close(2)</TT>, and so on).
|
||||
In addition to that, maintaining the caches coherent
|
||||
among CPUs on multiprocessor systems hurts performance when different threads
|
||||
running on different CPUs modify data items on the same cache line.
|
||||
<P>
|
||||
In order to improve load scalability, some applications employ a different
|
||||
type of MT architecture: they create one or more thread(s) <I>per task</I>
|
||||
rather than one thread <I>per connection</I>. For example, one small group
|
||||
of threads may be responsible for accepting client connections, another
|
||||
for request processing, and yet another for serving responses. The main
|
||||
advantage of this architecture is that it eliminates the tight coupling
|
||||
between the number of threads and number of simultaneous connections. However,
|
||||
in this architecture, different task-specific thread groups must share common
|
||||
work queues that must be protected by mutual exclusion locks (a typical
|
||||
producer-consumer problem). This adds synchronization overhead that causes an
|
||||
application to perform badly on multiprocessor systems. In other words, in
|
||||
this architecture, the application's system scalability is sacrificed for the
|
||||
sake of load scalability.
|
||||
<P>
|
||||
Of course, the usual nightmares of threaded programming, including data
|
||||
corruption, deadlocks, and race conditions, also make MT architecture (in any
|
||||
form) non-simplistic to use.
|
||||
<P>
|
||||
|
||||
<A NAME="EDSM">
|
||||
<H4>2.3 Event-Driven State Machine Architecture</H4>
|
||||
</A>
|
||||
<P>
|
||||
In the Event-Driven State Machine (EDSM) architecture, a single process
|
||||
is employed to concurrently process multiple connections. The basics of this
|
||||
architecture are described in Comer and Stevens
|
||||
<A HREF=#refs2>[Reference 2]</A>.
|
||||
The EDSM architecture performs one basic data-driven step associated with
|
||||
a particular connection at a time, thus multiplexing many concurrent
|
||||
connections. The process operates as a state machine that receives an event
|
||||
and then reacts to it.
|
||||
<P>
|
||||
In the idle state the EDSM calls <TT>select(2)</TT> or <TT>poll(2)</TT> to
|
||||
wait for network I/O events. When a particular file descriptor is ready for
|
||||
I/O, the EDSM completes the corresponding basic step (usually by invoking a
|
||||
handler function) and starts the next one. This architecture uses
|
||||
non-blocking system calls to perform asynchronous network I/O operations.
|
||||
For more details on non-blocking I/O see Stevens
|
||||
<A HREF=#refs3>[Reference 3]</A>.
|
||||
<P>
|
||||
To take advantage of hardware parallelism (real concurrency), multiple
|
||||
identical processes may be created. This is called Symmetric Multi-Process
|
||||
EDSM and is used, for example, in the Zeus Web Server
|
||||
(<A HREF=#refs4>[Reference 4]</A>). To more efficiently multiplex disk I/O,
|
||||
special "helper" processes may be created. This is called Asymmetric
|
||||
Multi-Process EDSM and was proposed for Web servers by Druschel
|
||||
and others <A HREF=#refs5>[Reference 5]</A>.
|
||||
<P>
|
||||
EDSM is probably the most scalable architecture for IAs.
|
||||
Because the number of simultaneous connections (virtual concurrency) is
|
||||
completely decoupled from the number of kernel execution vehicles (processes),
|
||||
this architecture has very good load scalability. It requires only minimal
|
||||
user-level resources to create and maintain additional connection.
|
||||
<P>
|
||||
Like MP applications, Multi-Process EDSM has very good system scalability
|
||||
because no resources are shared among different processes and there is no
|
||||
synchronization overhead.
|
||||
<P>
|
||||
Unfortunately, the EDSM architecture is monolithic rather than based on the
|
||||
concept of threads, so new applications generally need to be implemented from
|
||||
the ground up. In effect, the EDSM architecture simulates threads and their
|
||||
stacks the hard way.
|
||||
<P>
|
||||
|
||||
<A NAME="ST">
|
||||
<H3>3. State Threads Library</H3>
|
||||
</A>
|
||||
<P>
|
||||
The State Threads library combines the advantages of all of the above
|
||||
architectures. The interface preserves the programming simplicity of thread
|
||||
abstraction, allowing each simultaneous connection to be treated as a separate
|
||||
thread of execution within a single process. The underlying implementation is
|
||||
close to the EDSM architecture as the state of each particular concurrent
|
||||
session is saved in a separate memory segment.
|
||||
<P>
|
||||
|
||||
<H4>3.1 State Changes and Scheduling</H4>
|
||||
<P>
|
||||
The state of each concurrent session includes its stack environment
|
||||
(stack pointer, program counter, CPU registers) and its stack. Conceptually,
|
||||
a thread context switch can be viewed as a process changing its state. There
|
||||
are no kernel entities involved other than processes.
|
||||
Unlike other general-purpose threading libraries, the State Threads library
|
||||
is fully deterministic. The thread context switch (process state change) can
|
||||
only happen in a well-known set of functions (at I/O points or at explicit
|
||||
synchronization points). As a result, process-specific global data does not
|
||||
have to be protected by mutual exclusion locks in most cases. The entire
|
||||
application is free to use all the static variables and non-reentrant library
|
||||
functions it wants, greatly simplifying programming and debugging while
|
||||
increasing performance. This is somewhat similar to a <I>co-routine</I> model
|
||||
(co-operatively multitasked threads), except that no explicit yield is needed
|
||||
--
|
||||
sooner or later, a thread performs a blocking I/O operation and thus surrenders
|
||||
control. All threads of execution (simultaneous connections) have the
|
||||
same priority, so scheduling is non-preemptive, like in the EDSM architecture.
|
||||
Because IAs are data-driven (processing is limited by the size of network
|
||||
buffers and data arrival rates), scheduling is non-time-slicing.
|
||||
<P>
|
||||
Only two types of external events are handled by the library's
|
||||
scheduler, because only these events can be detected by
|
||||
<TT>select(2)</TT> or <TT>poll(2)</TT>: I/O events (a file descriptor is ready
|
||||
for I/O) and time events
|
||||
(some timeout has expired). However, other types of events (such as
|
||||
a signal sent to a process) can also be handled by converting them to I/O
|
||||
events. For example, a signal handling function can perform a write to a pipe
|
||||
(<TT>write(2)</TT> is reentrant/asynchronous-safe), thus converting a signal
|
||||
event to an I/O event.
|
||||
<P>
|
||||
To take advantage of hardware parallelism, as in the EDSM architecture,
|
||||
multiple processes can be created in either a symmetric or asymmetric manner.
|
||||
Process management is not in the library's scope but instead is left up to the
|
||||
application.
|
||||
<P>
|
||||
There are several general-purpose threading libraries that implement a
|
||||
<I>many-to-one</I> model (many user-level threads to one kernel execution
|
||||
vehicle), using the same basic techniques as the State Threads library
|
||||
(non-blocking I/O, event-driven scheduler, and so on). For an example, see GNU
|
||||
Portable Threads (<A HREF=#refs6>[Reference 6]</A>). Because they are
|
||||
general-purpose, these libraries have different objectives than the State
|
||||
Threads library. The State Threads library is <I>not</I> a general-purpose
|
||||
threading library,
|
||||
but rather an application library that targets only certain types of
|
||||
applications (IAs) in order to achieve the highest possible performance and
|
||||
scalability for those applications.
|
||||
<P>
|
||||
|
||||
<H4>3.2 Scalability</H4>
|
||||
<P>
|
||||
State threads are very lightweight user-level entities, and therefore creating
|
||||
and maintaining user connections requires minimal resources. An application
|
||||
using the State Threads library scales very well with the increasing number
|
||||
of connections.
|
||||
<P>
|
||||
On multiprocessor systems an application should create multiple processes
|
||||
to take advantage of hardware parallelism. Using multiple separate processes
|
||||
is the <I>only</I> way to achieve the highest possible system scalability.
|
||||
This is because duplicating per-process resources is the only way to avoid
|
||||
significant synchronization overhead on multiprocessor systems. Creating
|
||||
separate UNIX processes naturally offers resource duplication. Again,
|
||||
as in the EDSM architecture, there is no connection between the number of
|
||||
simultaneous connections (which may be very large and changes within a wide
|
||||
range) and the number of kernel entities (which is usually small and constant).
|
||||
In other words, the State Threads library makes it possible to multiplex a
|
||||
large number of simultaneous connections onto a much smaller number of
|
||||
separate processes, thus allowing an application to scale well with both
|
||||
the load and system size.
|
||||
<P>
|
||||
|
||||
<H4>3.3 Performance</H4>
|
||||
<P>
|
||||
Performance is one of the library's main objectives. The State Threads
|
||||
library is implemented to minimize the number of system calls and
|
||||
to make thread creation and context switching as fast as possible.
|
||||
For example, per-thread signal mask does not exist (unlike
|
||||
POSIX threads), so there is no need to save and restore a process's
|
||||
signal mask on every thread context switch. This eliminates two system
|
||||
calls per context switch. Signal events can be handled much more
|
||||
efficiently by converting them to I/O events (see above).
|
||||
<P>
|
||||
|
||||
<H4>3.4 Portability</H4>
|
||||
<P>
|
||||
The library uses the same general, underlying concepts as the EDSM
|
||||
architecture, including non-blocking I/O, file descriptors, and
|
||||
I/O multiplexing. These concepts are available in some form on most
|
||||
UNIX platforms, making the library very portable across many
|
||||
flavors of UNIX. There are only a few platform-dependent sections in the
|
||||
source.
|
||||
<P>
|
||||
|
||||
<H4>3.5 State Threads and NSPR</H4>
|
||||
<P>
|
||||
The State Threads library is a derivative of the Netscape Portable
|
||||
Runtime library (NSPR) <A HREF=#refs7>[Reference 7]</A>. The primary goal of
|
||||
NSPR is to provide a platform-independent layer for system facilities,
|
||||
where system facilities include threads, thread synchronization, and I/O.
|
||||
Performance and scalability are not the main concern of NSPR. The
|
||||
State Threads library addresses performance and scalability while
|
||||
remaining much smaller than NSPR. It is contained in 8 source files
|
||||
as opposed to more than 400, but provides all the functionality that
|
||||
is needed to write efficient IAs on UNIX-like platforms.
|
||||
<P>
|
||||
|
||||
<TABLE CELLPADDING=3>
|
||||
<TR>
|
||||
<TD></TD>
|
||||
<TH>NSPR</TH>
|
||||
<TH>State Threads</TH>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD><B>Lines of code</B></TD>
|
||||
<TD ALIGN=RIGHT>~150,000</TD>
|
||||
<TD ALIGN=RIGHT>~3000</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD><B>Dynamic library size <BR>(debug version)</B></TD>
|
||||
<TD></TD>
|
||||
<TD></TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>IRIX</TD>
|
||||
<TD ALIGN=RIGHT>~700 KB</TD>
|
||||
<TD ALIGN=RIGHT>~60 KB</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>Linux</TD>
|
||||
<TD ALIGN=RIGHT>~900 KB</TD>
|
||||
<TD ALIGN=RIGHT>~70 KB</TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
<P>
|
||||
|
||||
<H3>Conclusion</H3>
|
||||
<P>
|
||||
State Threads is an application library which provides a foundation for
|
||||
writing <A HREF=#IA>Internet Applications</A>. To summarize, it has the
|
||||
following <I>advantages</I>:
|
||||
<P>
|
||||
<UL>
|
||||
<LI>It allows the design of fast and highly scalable applications. An
|
||||
application will scale well with both load and number of CPUs.
|
||||
<P>
|
||||
<LI>It greatly simplifies application programming and debugging because, as a
|
||||
rule, no mutual exclusion locking is necessary and the entire application is
|
||||
free to use static variables and non-reentrant library functions.
|
||||
</UL>
|
||||
<P>
|
||||
The library's main <I>limitation</I>:
|
||||
<P>
|
||||
<UL>
|
||||
<LI>All I/O operations on sockets must use the State Thread library's I/O
|
||||
functions because only those functions perform thread scheduling and prevent
|
||||
the application's processes from blocking.
|
||||
</UL>
|
||||
<P>
|
||||
|
||||
<H3>References</H3>
|
||||
<OL>
|
||||
<A NAME="refs1">
|
||||
<LI> Apache Software Foundation,
|
||||
<A HREF="http://www.apache.org">http://www.apache.org</A>.
|
||||
<A NAME="refs2">
|
||||
<LI> Douglas E. Comer, David L. Stevens, <I>Internetworking With TCP/IP,
|
||||
Vol. III: Client-Server Programming And Applications</I>, Second Edition,
|
||||
Ch. 8, 12.
|
||||
<A NAME="refs3">
|
||||
<LI> W. Richard Stevens, <I>UNIX Network Programming</I>, Second Edition,
|
||||
Vol. 1, Ch. 15.
|
||||
<A NAME="refs4">
|
||||
<LI> Zeus Technology Limited,
|
||||
<A HREF="http://www.zeus.co.uk/">http://www.zeus.co.uk</A>.
|
||||
<A NAME="refs5">
|
||||
<LI> Peter Druschel, Vivek S. Pai, Willy Zwaenepoel,
|
||||
<A HREF="http://www.cs.rice.edu/~druschel/usenix99flash.ps.gz">
|
||||
Flash: An Efficient and Portable Web Server</A>. In <I>Proceedings of the
|
||||
USENIX 1999 Annual Technical Conference</I>, Monterey, CA, June 1999.
|
||||
<A NAME="refs6">
|
||||
<LI> GNU Portable Threads,
|
||||
<A HREF="http://www.gnu.org/software/pth/">http://www.gnu.org/software/pth/</A>.
|
||||
<A NAME="refs7">
|
||||
<LI> Netscape Portable Runtime,
|
||||
<A HREF="http://www.mozilla.org/docs/refList/refNSPR/">http://www.mozilla.org/docs/refList/refNSPR/</A>.
|
||||
</OL>
|
||||
|
||||
<H3>Other resources covering various architectural issues in IAs</H3>
|
||||
<OL START=8>
|
||||
<LI> Dan Kegel, <I>The C10K problem</I>,
|
||||
<A HREF="http://www.kegel.com/c10k.html">http://www.kegel.com/c10k.html</A>.
|
||||
</LI>
|
||||
<LI> James C. Hu, Douglas C. Schmidt, Irfan Pyarali, <I>JAWS: Understanding
|
||||
High Performance Web Systems</I>,
|
||||
<A HREF="http://www.cs.wustl.edu/~jxh/research/research.html">http://www.cs.wustl.edu/~jxh/research/research.html</A>.</LI>
|
||||
</OL>
|
||||
<P>
|
||||
<HR>
|
||||
<P>
|
||||
|
||||
<CENTER><FONT SIZE=-1>Portions created by SGI are Copyright © 2000
|
||||
Silicon Graphics, Inc. All rights reserved.</FONT></CENTER>
|
||||
<P>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
|
60
trunk/3rdparty/st-srs/docs/timeout_heap.txt
vendored
Normal file
60
trunk/3rdparty/st-srs/docs/timeout_heap.txt
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
How the timeout heap works
|
||||
|
||||
As of version 1.5, the State Threads Library represents the queue of
|
||||
sleeping threads using a heap data structure rather than a sorted
|
||||
linked list. This improves performance when there is a large number
|
||||
of sleeping threads, since insertion into a heap takes O(log N) time
|
||||
while insertion into a sorted list takes O(N) time. For example, in
|
||||
one test 1000 threads were created, each thread called st_usleep()
|
||||
with a random time interval, and then all the threads where
|
||||
immediately interrupted and joined before the sleeps had a chance to
|
||||
finish. The whole process was repeated 1000 times, for a total of a
|
||||
million sleep queue insertions and removals. With the old list-based
|
||||
sleep queue, this test took 100 seconds; now it takes only 12 seconds.
|
||||
|
||||
Heap data structures are typically based on dynamically resized
|
||||
arrays. However, since the existing ST code base was very nicely
|
||||
structured around linking the thread objects into pointer-based lists
|
||||
without the need for any auxiliary data structures, implementing the
|
||||
heap using a similar nodes-and-pointers based approach seemed more
|
||||
appropriate for ST than introducing a separate array.
|
||||
|
||||
Thus, the new ST timeout heap works by organizing the existing
|
||||
_st_thread_t objects in a balanced binary tree, just as they were
|
||||
previously organized into a doubly-linked, sorted list. The global
|
||||
_ST_SLEEPQ variable, formerly a linked list head, is now simply a
|
||||
pointer to the root of this tree, and the root node of the tree is the
|
||||
thread with the earliest timeout. Each thread object has two child
|
||||
pointers, "left" and "right", pointing to threads with later timeouts.
|
||||
|
||||
Each node in the tree is numbered with an integer index, corresponding
|
||||
to the array index in an array-based heap, and the tree is kept fully
|
||||
balanced and left-adjusted at all times. In other words, the tree
|
||||
consists of any number of fully populated top levels, followed by a
|
||||
single bottom level which may be partially populated, such that any
|
||||
existing nodes form a contiguous block to the left and the spaces for
|
||||
missing nodes form a contiguous block to the right. For example, if
|
||||
there are nine threads waiting for a timeout, they are numbered and
|
||||
arranged in a tree exactly as follows:
|
||||
|
||||
1
|
||||
/ \
|
||||
2 3
|
||||
/ \ / \
|
||||
4 5 6 7
|
||||
/ \
|
||||
8 9
|
||||
|
||||
Each node has either no children, only a left child, or both a left
|
||||
and a right child. Children always time out later than their parents
|
||||
(this is called the "heap invariant"), but when a node has two
|
||||
children, their mutual order is unspecified - the left child may time
|
||||
out before or after the right child. If a node is numbered N, its
|
||||
left child is numbered 2N, and its right child is numbered 2N+1.
|
||||
|
||||
There is no pointer from a child to its parent; all pointers point
|
||||
downward. Additions and deletions both work by starting at the root
|
||||
and traversing the tree towards the leaves, going left or right
|
||||
according to the binary digits forming the index of the destination
|
||||
node. As nodes are added or deleted, existing nodes are rearranged to
|
||||
maintain the heap invariant.
|
1413
trunk/3rdparty/st-srs/event.c
vendored
Normal file
1413
trunk/3rdparty/st-srs/event.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
115
trunk/3rdparty/st-srs/examples/Makefile
vendored
Normal file
115
trunk/3rdparty/st-srs/examples/Makefile
vendored
Normal file
|
@ -0,0 +1,115 @@
|
|||
#
|
||||
# Portions created by SGI are Copyright (C) 2000 Silicon Graphics, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# 3. Neither the name of Silicon Graphics, Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
##########################
|
||||
# Supported OSes:
|
||||
#
|
||||
# AIX
|
||||
# FREEBSD
|
||||
# HPUX
|
||||
# HPUX_64
|
||||
# IRIX
|
||||
# IRIX_64
|
||||
# LINUX
|
||||
# LINUX_IA64
|
||||
# NETBSD
|
||||
# OPENBSD
|
||||
# OSF1
|
||||
# SOLARIS
|
||||
# SOLARIS_64
|
||||
|
||||
##########################
|
||||
|
||||
CC = cc
|
||||
|
||||
SHELL = /bin/sh
|
||||
ECHO = /bin/echo
|
||||
|
||||
DEPTH = ..
|
||||
BUILD =
|
||||
TARGETDIR =
|
||||
|
||||
DEFINES =
|
||||
CFLAGS =
|
||||
OTHER_FLAGS =
|
||||
|
||||
OBJDIR = $(DEPTH)/$(TARGETDIR)
|
||||
INCDIR = $(DEPTH)/$(TARGETDIR)
|
||||
LIBST = $(OBJDIR)/libst.a
|
||||
HEADER = $(INCDIR)/st.h
|
||||
|
||||
LIBRESOLV =
|
||||
EXTRALIBS =
|
||||
|
||||
ifeq ($(OS),)
|
||||
EXAMPLES = unknown
|
||||
else
|
||||
EXAMPLES = $(OBJDIR)/lookupdns $(OBJDIR)/proxy $(OBJDIR)/server
|
||||
endif
|
||||
|
||||
|
||||
##########################
|
||||
# Platform section.
|
||||
#
|
||||
|
||||
ifeq (DARWIN, $(findstring DARWIN, $(OS)))
|
||||
LIBRESOLV = -lresolv
|
||||
endif
|
||||
|
||||
ifeq (LINUX, $(findstring LINUX, $(OS)))
|
||||
LIBRESOLV = -lresolv
|
||||
endif
|
||||
|
||||
ifeq (SOLARIS, $(findstring SOLARIS, $(OS)))
|
||||
LIBRESOLV = -lresolv
|
||||
EXTRALIBS = -lsocket -lnsl
|
||||
endif
|
||||
|
||||
#
|
||||
# End of platform section.
|
||||
##########################
|
||||
|
||||
|
||||
all: $(EXAMPLES)
|
||||
|
||||
$(OBJDIR)/lookupdns: lookupdns.c $(OBJDIR)/res.o $(LIBST) $(HEADER)
|
||||
$(CC) $(CFLAGS) -I$(INCDIR) lookupdns.c $(OBJDIR)/res.o $(LIBST) $(LIBRESOLV) $(EXTRALIBS) -o $@
|
||||
|
||||
$(OBJDIR)/proxy: proxy.c $(LIBST) $(HEADER)
|
||||
$(CC) $(CFLAGS) -I$(INCDIR) proxy.c $(LIBST) $(EXTRALIBS) -o $@
|
||||
|
||||
$(OBJDIR)/server: server.c $(OBJDIR)/error.o $(LIBST) $(HEADER)
|
||||
$(CC) $(CFLAGS) -I$(INCDIR) server.c $(OBJDIR)/error.o $(LIBST) $(EXTRALIBS) -o $@
|
||||
|
||||
$(OBJDIR)/%.o: %.c
|
||||
$(CC) $(CFLAGS) -I$(INCDIR) -c $< -o $@
|
||||
|
||||
.DEFAULT:
|
||||
@cd $(DEPTH); $(MAKE) $@
|
||||
|
98
trunk/3rdparty/st-srs/examples/README
vendored
Normal file
98
trunk/3rdparty/st-srs/examples/README
vendored
Normal file
|
@ -0,0 +1,98 @@
|
|||
Portions created by SGI are Copyright (C) 2000 Silicon Graphics, Inc.
|
||||
All Rights Reserved.
|
||||
|
||||
|
||||
This directory contains three example programs.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
PROGRAM
|
||||
|
||||
lookupdns
|
||||
|
||||
FILES
|
||||
|
||||
lookupdns.c
|
||||
res.c
|
||||
|
||||
USAGE
|
||||
|
||||
lookupdns <hostname1> [<hostname2>] ...
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
This program performs asynchronous DNS host name resolution and reports
|
||||
IP address for each <hostname> specified as a command line argument.
|
||||
One ST thread is created for each host name. All threads do host name
|
||||
resolution concurrently.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
PROGRAM
|
||||
|
||||
proxy
|
||||
|
||||
FILES
|
||||
|
||||
proxy.c
|
||||
|
||||
USAGE
|
||||
|
||||
proxy -l <local_addr> -r <remote_addr> [-p <num_processes>] [-S]
|
||||
|
||||
-l <local_addr> bind to local address specified as [<host>]:<port>
|
||||
-r <remote_addr> connect to remote address specified as <host>:<port>
|
||||
-p <num_processes> create specified number of processes
|
||||
-S serialize accept() calls from different processes
|
||||
on the same listening socket (if needed).
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
This program acts as a generic gateway. It listens for connections to a
|
||||
local address. Upon accepting a client connection, it connects to the
|
||||
specified remote address and then just pumps the data through without any
|
||||
modification.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
PROGRAM
|
||||
|
||||
server
|
||||
|
||||
FILES
|
||||
|
||||
server.c
|
||||
error.c
|
||||
|
||||
USAGE
|
||||
|
||||
server -l <log_directory> [<options>]
|
||||
|
||||
-l <log_directory> open all log files in specified directory.
|
||||
|
||||
Possible options:
|
||||
|
||||
-b <host>:<port> bind to specified address (multiple addresses
|
||||
are permitted)
|
||||
-p <num_processes> create specified number of processes
|
||||
-t <min_thr>:<max_thr> specify thread limits per listening socket
|
||||
across all processes
|
||||
-u <user> change server's user id to specified value
|
||||
-q <backlog> set max length of pending connections queue
|
||||
-a enable access logging
|
||||
-i run in interactive mode (useful for debugging)
|
||||
-S serialize accept() calls from different processes
|
||||
on the same listening socket (if needed).
|
||||
|
||||
DESCRIPTION
|
||||
|
||||
This program is a general server example. It accepts a client connection
|
||||
and outputs a short HTML page. It can be easily adapted to provide
|
||||
other services.
|
||||
|
||||
|
||||
---------------------------------------------------------------------------
|
||||
|
168
trunk/3rdparty/st-srs/examples/error.c
vendored
Normal file
168
trunk/3rdparty/st-srs/examples/error.c
vendored
Normal file
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* Portions created by SGI are Copyright (C) 2000 Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of Silicon Graphics, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include "st.h"
|
||||
|
||||
/*
|
||||
* Simple error reporting functions.
|
||||
* Suggested in W. Richard Stevens' "Advanced Programming in UNIX
|
||||
* Environment".
|
||||
*/
|
||||
|
||||
#define MAXLINE 4096 /* max line length */
|
||||
|
||||
static void err_doit(int, int, const char *, va_list);
|
||||
|
||||
|
||||
/*
|
||||
* Nonfatal error related to a system call.
|
||||
* Print a message and return.
|
||||
*/
|
||||
void err_sys_report(int fd, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
err_doit(fd, 1, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fatal error related to a system call.
|
||||
* Print a message and terminate.
|
||||
*/
|
||||
void err_sys_quit(int fd, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
err_doit(fd, 1, fmt, ap);
|
||||
va_end(ap);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fatal error related to a system call.
|
||||
* Print a message, dump core, and terminate.
|
||||
*/
|
||||
void err_sys_dump(int fd, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
err_doit(fd, 1, fmt, ap);
|
||||
va_end(ap);
|
||||
abort(); /* dump core and terminate */
|
||||
exit(1); /* shouldn't get here */
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Nonfatal error unrelated to a system call.
|
||||
* Print a message and return.
|
||||
*/
|
||||
void err_report(int fd, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
err_doit(fd, 0, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fatal error unrelated to a system call.
|
||||
* Print a message and terminate.
|
||||
*/
|
||||
void err_quit(int fd, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
err_doit(fd, 0, fmt, ap);
|
||||
va_end(ap);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return a pointer to a string containing current time.
|
||||
*/
|
||||
char *err_tstamp(void)
|
||||
{
|
||||
static char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
|
||||
static char str[32];
|
||||
static time_t lastt = 0;
|
||||
struct tm *tmp;
|
||||
time_t currt = st_time();
|
||||
|
||||
if (currt == lastt)
|
||||
return str;
|
||||
|
||||
tmp = localtime(&currt);
|
||||
sprintf(str, "[%02d/%s/%d:%02d:%02d:%02d] ", tmp->tm_mday,
|
||||
months[tmp->tm_mon], 1900 + tmp->tm_year, tmp->tm_hour,
|
||||
tmp->tm_min, tmp->tm_sec);
|
||||
lastt = currt;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Print a message and return to caller.
|
||||
* Caller specifies "errnoflag".
|
||||
*/
|
||||
static void err_doit(int fd, int errnoflag, const char *fmt, va_list ap)
|
||||
{
|
||||
int errno_save;
|
||||
char buf[MAXLINE];
|
||||
|
||||
errno_save = errno; /* value caller might want printed */
|
||||
strcpy(buf, err_tstamp()); /* prepend a message with time stamp */
|
||||
vsprintf(buf + strlen(buf), fmt, ap);
|
||||
if (errnoflag)
|
||||
sprintf(buf + strlen(buf), ": %s\n", strerror(errno_save));
|
||||
else
|
||||
strcat(buf, "\n");
|
||||
write(fd, buf, strlen(buf));
|
||||
errno = errno_save;
|
||||
}
|
||||
|
103
trunk/3rdparty/st-srs/examples/lookupdns.c
vendored
Normal file
103
trunk/3rdparty/st-srs/examples/lookupdns.c
vendored
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Portions created by SGI are Copyright (C) 2000 Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of Silicon Graphics, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include "st.h"
|
||||
|
||||
#if !defined(NETDB_INTERNAL) && defined(h_NETDB_INTERNAL)
|
||||
#define NETDB_INTERNAL h_NETDB_INTERNAL
|
||||
#endif
|
||||
|
||||
/* Resolution timeout (in microseconds) */
|
||||
#define TIMEOUT (2*1000000LL)
|
||||
|
||||
/* External function defined in the res.c file */
|
||||
int dns_getaddr(const char *host, struct in_addr *addr, st_utime_t timeout);
|
||||
|
||||
|
||||
void *do_resolve(void *host)
|
||||
{
|
||||
struct in_addr addr;
|
||||
|
||||
/* Use dns_getaddr() instead of gethostbyname(3) to get IP address */
|
||||
if (dns_getaddr(host, &addr, TIMEOUT) < 0) {
|
||||
fprintf(stderr, "dns_getaddr: can't resolve %s: ", (char *)host);
|
||||
if (h_errno == NETDB_INTERNAL)
|
||||
perror("");
|
||||
else
|
||||
herror("");
|
||||
} else
|
||||
printf("%-40s %s\n", (char *)host, inet_ntoa(addr));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Asynchronous DNS host name resolution. This program creates one
|
||||
* ST thread for each host name (specified as command line arguments).
|
||||
* All threads do host name resolution concurrently.
|
||||
*/
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Usage: %s <hostname1> [<hostname2>] ...\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (st_init() < 0) {
|
||||
perror("st_init");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
/* Create a separate thread for each host name */
|
||||
if (st_thread_create(do_resolve, argv[i], 0, 0) == NULL) {
|
||||
perror("st_thread_create");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
st_thread_exit(NULL);
|
||||
|
||||
/* NOTREACHED */
|
||||
return 1;
|
||||
}
|
||||
|
541
trunk/3rdparty/st-srs/examples/proxy.c
vendored
Normal file
541
trunk/3rdparty/st-srs/examples/proxy.c
vendored
Normal file
|
@ -0,0 +1,541 @@
|
|||
/*
|
||||
* Portions created by SGI are Copyright (C) 2000 Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of Silicon Graphics, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include "st.h"
|
||||
|
||||
#define IOBUFSIZE (16*1024)
|
||||
|
||||
#define IOV_LEN 256
|
||||
#define IOV_COUNT (IOBUFSIZE / IOV_LEN)
|
||||
|
||||
#ifndef INADDR_NONE
|
||||
#define INADDR_NONE 0xffffffff
|
||||
#endif
|
||||
|
||||
static char *prog; /* Program name */
|
||||
static struct sockaddr_in rmt_addr; /* Remote address */
|
||||
|
||||
static unsigned long testing;
|
||||
#define TESTING_VERBOSE 0x1
|
||||
#define TESTING_READV 0x2
|
||||
#define TESTING_READ_RESID 0x4
|
||||
#define TESTING_WRITEV 0x8
|
||||
#define TESTING_WRITE_RESID 0x10
|
||||
|
||||
static void read_address(const char *str, struct sockaddr_in *sin);
|
||||
static void start_daemon(void);
|
||||
static int cpu_count(void);
|
||||
static void set_concurrency(int nproc);
|
||||
static void *handle_request(void *arg);
|
||||
static void print_sys_error(const char *msg);
|
||||
|
||||
|
||||
/*
|
||||
* This program acts as a generic gateway. It listens for connections
|
||||
* to a local address ('-l' option). Upon accepting a client connection,
|
||||
* it connects to the specified remote address ('-r' option) and then
|
||||
* just pumps the data through without any modification.
|
||||
*/
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
extern char *optarg;
|
||||
int opt, sock, n;
|
||||
int laddr, raddr, num_procs, alt_ev, one_process;
|
||||
int serialize_accept = 0;
|
||||
struct sockaddr_in lcl_addr, cli_addr;
|
||||
st_netfd_t cli_nfd, srv_nfd;
|
||||
|
||||
prog = argv[0];
|
||||
num_procs = laddr = raddr = alt_ev = one_process = 0;
|
||||
|
||||
/* Parse arguments */
|
||||
while((opt = getopt(argc, argv, "l:r:p:Saht:X")) != EOF) {
|
||||
switch (opt) {
|
||||
case 'a':
|
||||
alt_ev = 1;
|
||||
break;
|
||||
case 'l':
|
||||
read_address(optarg, &lcl_addr);
|
||||
laddr = 1;
|
||||
break;
|
||||
case 'r':
|
||||
read_address(optarg, &rmt_addr);
|
||||
if (rmt_addr.sin_addr.s_addr == INADDR_ANY) {
|
||||
fprintf(stderr, "%s: invalid remote address: %s\n", prog, optarg);
|
||||
exit(1);
|
||||
}
|
||||
raddr = 1;
|
||||
break;
|
||||
case 'p':
|
||||
num_procs = atoi(optarg);
|
||||
if (num_procs < 1) {
|
||||
fprintf(stderr, "%s: invalid number of processes: %s\n", prog, optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
/*
|
||||
* Serialization decision is tricky on some platforms. For example,
|
||||
* Solaris 2.6 and above has kernel sockets implementation, so supposedly
|
||||
* there is no need for serialization. The ST library may be compiled
|
||||
* on one OS version, but used on another, so the need for serialization
|
||||
* should be determined at run time by the application. Since it's just
|
||||
* an example, the serialization decision is left up to user.
|
||||
* Only on platforms where the serialization is never needed on any OS
|
||||
* version st_netfd_serialize_accept() is a no-op.
|
||||
*/
|
||||
serialize_accept = 1;
|
||||
break;
|
||||
case 't':
|
||||
testing = strtoul(optarg, NULL, 0);
|
||||
break;
|
||||
case 'X':
|
||||
one_process = 1;
|
||||
break;
|
||||
case 'h':
|
||||
case '?':
|
||||
fprintf(stderr, "Usage: %s [options] -l <[host]:port> -r <host:port>\n",
|
||||
prog);
|
||||
fprintf(stderr, "options are:\n");
|
||||
fprintf(stderr, " -p <num_processes> number of parallel processes\n");
|
||||
fprintf(stderr, " -S serialize accepts\n");
|
||||
fprintf(stderr, " -a use alternate event system\n");
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, " -t mask testing/debugging mode\n");
|
||||
fprintf(stderr, " -X one process, don't daemonize\n");
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
if (!laddr) {
|
||||
fprintf(stderr, "%s: local address required\n", prog);
|
||||
exit(1);
|
||||
}
|
||||
if (!raddr) {
|
||||
fprintf(stderr, "%s: remote address required\n", prog);
|
||||
exit(1);
|
||||
}
|
||||
if (num_procs == 0)
|
||||
num_procs = cpu_count();
|
||||
|
||||
fprintf(stderr, "%s: starting proxy daemon on %s:%d\n", prog,
|
||||
inet_ntoa(lcl_addr.sin_addr), ntohs(lcl_addr.sin_port));
|
||||
|
||||
/* Start the daemon */
|
||||
if (one_process)
|
||||
num_procs = 1;
|
||||
else
|
||||
start_daemon();
|
||||
|
||||
if (alt_ev)
|
||||
st_set_eventsys(ST_EVENTSYS_ALT);
|
||||
|
||||
/* Initialize the ST library */
|
||||
if (st_init() < 0) {
|
||||
print_sys_error("st_init");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Create and bind listening socket */
|
||||
if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
|
||||
print_sys_error("socket");
|
||||
exit(1);
|
||||
}
|
||||
n = 1;
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&n, sizeof(n)) < 0) {
|
||||
print_sys_error("setsockopt");
|
||||
exit(1);
|
||||
}
|
||||
if (bind(sock, (struct sockaddr *)&lcl_addr, sizeof(lcl_addr)) < 0) {
|
||||
print_sys_error("bind");
|
||||
exit(1);
|
||||
}
|
||||
listen(sock, 128);
|
||||
if ((srv_nfd = st_netfd_open_socket(sock)) == NULL) {
|
||||
print_sys_error("st_netfd_open");
|
||||
exit(1);
|
||||
}
|
||||
/* See the comment regarding serialization decision above */
|
||||
if (num_procs > 1 && serialize_accept && st_netfd_serialize_accept(srv_nfd)
|
||||
< 0) {
|
||||
print_sys_error("st_netfd_serialize_accept");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Start server processes */
|
||||
if (!one_process)
|
||||
set_concurrency(num_procs);
|
||||
|
||||
for ( ; ; ) {
|
||||
n = sizeof(cli_addr);
|
||||
cli_nfd = st_accept(srv_nfd, (struct sockaddr *)&cli_addr, &n,
|
||||
ST_UTIME_NO_TIMEOUT);
|
||||
if (cli_nfd == NULL) {
|
||||
print_sys_error("st_accept");
|
||||
exit(1);
|
||||
}
|
||||
if (st_thread_create(handle_request, cli_nfd, 0, 0) == NULL) {
|
||||
print_sys_error("st_thread_create");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* NOTREACHED */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void read_address(const char *str, struct sockaddr_in *sin)
|
||||
{
|
||||
char host[128], *p;
|
||||
struct hostent *hp;
|
||||
unsigned short port;
|
||||
|
||||
strcpy(host, str);
|
||||
if ((p = strchr(host, ':')) == NULL) {
|
||||
fprintf(stderr, "%s: invalid address: %s\n", prog, host);
|
||||
exit(1);
|
||||
}
|
||||
*p++ = '\0';
|
||||
port = (unsigned short) atoi(p);
|
||||
if (port < 1) {
|
||||
fprintf(stderr, "%s: invalid port: %s\n", prog, p);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
memset(sin, 0, sizeof(struct sockaddr_in));
|
||||
sin->sin_family = AF_INET;
|
||||
sin->sin_port = htons(port);
|
||||
if (host[0] == '\0') {
|
||||
sin->sin_addr.s_addr = INADDR_ANY;
|
||||
return;
|
||||
}
|
||||
sin->sin_addr.s_addr = inet_addr(host);
|
||||
if (sin->sin_addr.s_addr == INADDR_NONE) {
|
||||
/* not dotted-decimal */
|
||||
if ((hp = gethostbyname(host)) == NULL) {
|
||||
fprintf(stderr, "%s: can't resolve address: %s\n", prog, host);
|
||||
exit(1);
|
||||
}
|
||||
memcpy(&sin->sin_addr, hp->h_addr, hp->h_length);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static void show_iov(const struct iovec *iov, int niov)
|
||||
{
|
||||
int i;
|
||||
size_t total;
|
||||
|
||||
printf("iov %p has %d entries:\n", iov, niov);
|
||||
total = 0;
|
||||
for (i = 0; i < niov; i++) {
|
||||
printf("iov[%3d] iov_base=%p iov_len=0x%lx(%lu)\n",
|
||||
i, iov[i].iov_base, (unsigned long) iov[i].iov_len,
|
||||
(unsigned long) iov[i].iov_len);
|
||||
total += iov[i].iov_len;
|
||||
}
|
||||
printf("total 0x%lx(%ld)\n", (unsigned long) total, (unsigned long) total);
|
||||
}
|
||||
|
||||
/*
|
||||
* This version is tricked out to test all the
|
||||
* st_(read|write)v?(_resid)? variants. Use the non-DEBUG version for
|
||||
* anything serious. st_(read|write) are all this function really
|
||||
* needs.
|
||||
*/
|
||||
static int pass(st_netfd_t in, st_netfd_t out)
|
||||
{
|
||||
char buf[IOBUFSIZE];
|
||||
struct iovec iov[IOV_COUNT];
|
||||
int ioviter, nw, nr;
|
||||
|
||||
if (testing & TESTING_READV) {
|
||||
for (ioviter = 0; ioviter < IOV_COUNT; ioviter++) {
|
||||
iov[ioviter].iov_base = &buf[ioviter * IOV_LEN];
|
||||
iov[ioviter].iov_len = IOV_LEN;
|
||||
}
|
||||
if (testing & TESTING_VERBOSE) {
|
||||
printf("readv(%p)...\n", in);
|
||||
show_iov(iov, IOV_COUNT);
|
||||
}
|
||||
if (testing & TESTING_READ_RESID) {
|
||||
struct iovec *riov = iov;
|
||||
int riov_cnt = IOV_COUNT;
|
||||
if (st_readv_resid(in, &riov, &riov_cnt, ST_UTIME_NO_TIMEOUT) == 0) {
|
||||
if (testing & TESTING_VERBOSE) {
|
||||
printf("resid\n");
|
||||
show_iov(riov, riov_cnt);
|
||||
printf("full\n");
|
||||
show_iov(iov, IOV_COUNT);
|
||||
}
|
||||
nr = 0;
|
||||
for (ioviter = 0; ioviter < IOV_COUNT; ioviter++)
|
||||
nr += iov[ioviter].iov_len;
|
||||
nr = IOBUFSIZE - nr;
|
||||
} else
|
||||
nr = -1;
|
||||
} else
|
||||
nr = (int) st_readv(in, iov, IOV_COUNT, ST_UTIME_NO_TIMEOUT);
|
||||
} else {
|
||||
if (testing & TESTING_READ_RESID) {
|
||||
size_t resid = IOBUFSIZE;
|
||||
if (st_read_resid(in, buf, &resid, ST_UTIME_NO_TIMEOUT) == 0)
|
||||
nr = IOBUFSIZE - resid;
|
||||
else
|
||||
nr = -1;
|
||||
} else
|
||||
nr = (int) st_read(in, buf, IOBUFSIZE, ST_UTIME_NO_TIMEOUT);
|
||||
}
|
||||
if (testing & TESTING_VERBOSE)
|
||||
printf("got 0x%x(%d) E=%d\n", nr, nr, errno);
|
||||
|
||||
if (nr <= 0)
|
||||
return 0;
|
||||
|
||||
if (testing & TESTING_WRITEV) {
|
||||
for (nw = 0, ioviter = 0; nw < nr;
|
||||
nw += iov[ioviter].iov_len, ioviter++) {
|
||||
iov[ioviter].iov_base = &buf[nw];
|
||||
iov[ioviter].iov_len = nr - nw;
|
||||
if (iov[ioviter].iov_len > IOV_LEN)
|
||||
iov[ioviter].iov_len = IOV_LEN;
|
||||
}
|
||||
if (testing & TESTING_VERBOSE) {
|
||||
printf("writev(%p)...\n", out);
|
||||
show_iov(iov, ioviter);
|
||||
}
|
||||
if (testing & TESTING_WRITE_RESID) {
|
||||
struct iovec *riov = iov;
|
||||
int riov_cnt = ioviter;
|
||||
if (st_writev_resid(out, &riov, &riov_cnt, ST_UTIME_NO_TIMEOUT) == 0) {
|
||||
if (testing & TESTING_VERBOSE) {
|
||||
printf("resid\n");
|
||||
show_iov(riov, riov_cnt);
|
||||
printf("full\n");
|
||||
show_iov(iov, ioviter);
|
||||
}
|
||||
nw = 0;
|
||||
while (--ioviter >= 0)
|
||||
nw += iov[ioviter].iov_len;
|
||||
nw = nr - nw;
|
||||
} else
|
||||
nw = -1;
|
||||
} else
|
||||
nw = st_writev(out, iov, ioviter, ST_UTIME_NO_TIMEOUT);
|
||||
} else {
|
||||
if (testing & TESTING_WRITE_RESID) {
|
||||
size_t resid = nr;
|
||||
if (st_write_resid(out, buf, &resid, ST_UTIME_NO_TIMEOUT) == 0)
|
||||
nw = nr - resid;
|
||||
else
|
||||
nw = -1;
|
||||
} else
|
||||
nw = st_write(out, buf, nr, ST_UTIME_NO_TIMEOUT);
|
||||
}
|
||||
if (testing & TESTING_VERBOSE)
|
||||
printf("put 0x%x(%d) E=%d\n", nw, nw, errno);
|
||||
|
||||
if (nw != nr)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
#else /* DEBUG */
|
||||
/*
|
||||
* This version is the simple one suitable for serious use.
|
||||
*/
|
||||
static int pass(st_netfd_t in, st_netfd_t out)
|
||||
{
|
||||
char buf[IOBUFSIZE];
|
||||
int nw, nr;
|
||||
|
||||
nr = (int) st_read(in, buf, IOBUFSIZE, ST_UTIME_NO_TIMEOUT);
|
||||
if (nr <= 0)
|
||||
return 0;
|
||||
|
||||
nw = st_write(out, buf, nr, ST_UTIME_NO_TIMEOUT);
|
||||
if (nw != nr)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void *handle_request(void *arg)
|
||||
{
|
||||
struct pollfd pds[2];
|
||||
st_netfd_t cli_nfd, rmt_nfd;
|
||||
int sock;
|
||||
|
||||
cli_nfd = (st_netfd_t) arg;
|
||||
pds[0].fd = st_netfd_fileno(cli_nfd);
|
||||
pds[0].events = POLLIN;
|
||||
|
||||
/* Connect to remote host */
|
||||
if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
|
||||
print_sys_error("socket");
|
||||
goto done;
|
||||
}
|
||||
if ((rmt_nfd = st_netfd_open_socket(sock)) == NULL) {
|
||||
print_sys_error("st_netfd_open_socket");
|
||||
close(sock);
|
||||
goto done;
|
||||
}
|
||||
if (st_connect(rmt_nfd, (struct sockaddr *)&rmt_addr,
|
||||
sizeof(rmt_addr), ST_UTIME_NO_TIMEOUT) < 0) {
|
||||
print_sys_error("st_connect");
|
||||
st_netfd_close(rmt_nfd);
|
||||
goto done;
|
||||
}
|
||||
pds[1].fd = sock;
|
||||
pds[1].events = POLLIN;
|
||||
|
||||
/*
|
||||
* Now just pump the data through.
|
||||
* XXX This should use one thread for each direction for true full-duplex.
|
||||
*/
|
||||
for ( ; ; ) {
|
||||
pds[0].revents = 0;
|
||||
pds[1].revents = 0;
|
||||
|
||||
if (st_poll(pds, 2, ST_UTIME_NO_TIMEOUT) <= 0) {
|
||||
print_sys_error("st_poll");
|
||||
break;
|
||||
}
|
||||
|
||||
if (pds[0].revents & POLLIN) {
|
||||
if (!pass(cli_nfd, rmt_nfd))
|
||||
break;
|
||||
}
|
||||
|
||||
if (pds[1].revents & POLLIN) {
|
||||
if (!pass(rmt_nfd, cli_nfd))
|
||||
break;
|
||||
}
|
||||
}
|
||||
st_netfd_close(rmt_nfd);
|
||||
|
||||
done:
|
||||
|
||||
st_netfd_close(cli_nfd);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void start_daemon(void)
|
||||
{
|
||||
pid_t pid;
|
||||
|
||||
/* Start forking */
|
||||
if ((pid = fork()) < 0) {
|
||||
print_sys_error("fork");
|
||||
exit(1);
|
||||
}
|
||||
if (pid > 0)
|
||||
exit(0); /* parent */
|
||||
|
||||
/* First child process */
|
||||
setsid(); /* become session leader */
|
||||
|
||||
if ((pid = fork()) < 0) {
|
||||
print_sys_error("fork");
|
||||
exit(1);
|
||||
}
|
||||
if (pid > 0) /* first child */
|
||||
exit(0);
|
||||
|
||||
chdir("/");
|
||||
umask(022);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create separate processes ("virtual processors"). Since it's just an
|
||||
* example, there is no watchdog - the parent just exits leaving children
|
||||
* on their own.
|
||||
*/
|
||||
static void set_concurrency(int nproc)
|
||||
{
|
||||
pid_t pid;
|
||||
int i;
|
||||
|
||||
if (nproc < 1)
|
||||
nproc = 1;
|
||||
|
||||
for (i = 0; i < nproc; i++) {
|
||||
if ((pid = fork()) < 0) {
|
||||
print_sys_error("fork");
|
||||
exit(1);
|
||||
}
|
||||
/* Child returns */
|
||||
if (pid == 0)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Parent just exits */
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static int cpu_count(void)
|
||||
{
|
||||
int n;
|
||||
|
||||
#if defined (_SC_NPROCESSORS_ONLN)
|
||||
n = (int) sysconf(_SC_NPROCESSORS_ONLN);
|
||||
#elif defined (_SC_NPROC_ONLN)
|
||||
n = (int) sysconf(_SC_NPROC_ONLN);
|
||||
#elif defined (HPUX)
|
||||
#include <sys/mpctl.h>
|
||||
n = mpctl(MPC_GETNUMSPUS, 0, 0);
|
||||
#else
|
||||
n = -1;
|
||||
errno = ENOSYS;
|
||||
#endif
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
static void print_sys_error(const char *msg)
|
||||
{
|
||||
fprintf(stderr, "%s: %s: %s\n", prog, msg, strerror(errno));
|
||||
}
|
||||
|
305
trunk/3rdparty/st-srs/examples/res.c
vendored
Normal file
305
trunk/3rdparty/st-srs/examples/res.c
vendored
Normal file
|
@ -0,0 +1,305 @@
|
|||
/*
|
||||
* Copyright (c) 1985, 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Portions created by SGI are Copyright (C) 2000 Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of Silicon Graphics, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined (DARWIN)
|
||||
#define BIND_8_COMPAT
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
#include <netdb.h>
|
||||
#include <errno.h>
|
||||
#include "st.h"
|
||||
|
||||
#define MAXPACKET 1024
|
||||
|
||||
#if !defined(NETDB_INTERNAL) && defined(h_NETDB_INTERNAL)
|
||||
#define NETDB_INTERNAL h_NETDB_INTERNAL
|
||||
#endif
|
||||
|
||||
/* New in Solaris 7 */
|
||||
#if !defined(_getshort) && defined(ns_get16)
|
||||
#define _getshort(cp) ns_get16(cp)
|
||||
#endif
|
||||
|
||||
typedef union {
|
||||
HEADER hdr;
|
||||
u_char buf[MAXPACKET];
|
||||
} querybuf_t;
|
||||
|
||||
|
||||
static int parse_answer(querybuf_t *ans, int len, struct in_addr *addr)
|
||||
{
|
||||
char buf[MAXPACKET];
|
||||
HEADER *ahp;
|
||||
u_char *cp, *eoa;
|
||||
int type, n;
|
||||
|
||||
ahp = &ans->hdr;
|
||||
eoa = ans->buf + len;
|
||||
cp = ans->buf + sizeof(HEADER);
|
||||
|
||||
while (ahp->qdcount > 0) {
|
||||
ahp->qdcount--;
|
||||
cp += dn_skipname(cp, eoa) + QFIXEDSZ;
|
||||
}
|
||||
while (ahp->ancount > 0 && cp < eoa) {
|
||||
ahp->ancount--;
|
||||
if ((n = dn_expand(ans->buf, eoa, cp, buf, sizeof(buf))) < 0)
|
||||
break;
|
||||
cp += n;
|
||||
type = _getshort(cp);
|
||||
cp += 8;
|
||||
n = _getshort(cp);
|
||||
cp += 2;
|
||||
if (type == T_CNAME) {
|
||||
cp += n;
|
||||
continue;
|
||||
}
|
||||
memcpy(addr, cp, n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
h_errno = TRY_AGAIN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int query_domain(st_netfd_t nfd, const char *name, struct in_addr *addr,
|
||||
st_utime_t timeout)
|
||||
{
|
||||
querybuf_t qbuf;
|
||||
u_char *buf = qbuf.buf;
|
||||
HEADER *hp = &qbuf.hdr;
|
||||
int blen = sizeof(qbuf);
|
||||
int i, len, id;
|
||||
|
||||
for (i = 0; i < _res.nscount; i++) {
|
||||
len = res_mkquery(QUERY, name, C_IN, T_A, NULL, 0, NULL, buf, blen);
|
||||
if (len <= 0) {
|
||||
h_errno = NO_RECOVERY;
|
||||
return -1;
|
||||
}
|
||||
id = hp->id;
|
||||
|
||||
if (st_sendto(nfd, buf, len, (struct sockaddr *)&(_res.nsaddr_list[i]),
|
||||
sizeof(struct sockaddr), timeout) != len) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
/* EINTR means interrupt by other thread, NOT by a caught signal */
|
||||
if (errno == EINTR)
|
||||
return -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Wait for reply */
|
||||
do {
|
||||
len = st_recvfrom(nfd, buf, blen, NULL, NULL, timeout);
|
||||
if (len <= 0)
|
||||
break;
|
||||
} while (id != hp->id);
|
||||
|
||||
if (len < HFIXEDSZ) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
if (len >= 0)
|
||||
errno = EMSGSIZE;
|
||||
else if (errno == EINTR) /* see the comment above */
|
||||
return -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
hp->ancount = ntohs(hp->ancount);
|
||||
hp->qdcount = ntohs(hp->qdcount);
|
||||
if ((hp->rcode != NOERROR) || (hp->ancount == 0)) {
|
||||
switch (hp->rcode) {
|
||||
case NXDOMAIN:
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
break;
|
||||
case SERVFAIL:
|
||||
h_errno = TRY_AGAIN;
|
||||
break;
|
||||
case NOERROR:
|
||||
h_errno = NO_DATA;
|
||||
break;
|
||||
case FORMERR:
|
||||
case NOTIMP:
|
||||
case REFUSED:
|
||||
default:
|
||||
h_errno = NO_RECOVERY;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (parse_answer(&qbuf, len, addr) == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
#define CLOSE_AND_RETURN(ret) \
|
||||
{ \
|
||||
n = errno; \
|
||||
st_netfd_close(nfd); \
|
||||
errno = n; \
|
||||
return (ret); \
|
||||
}
|
||||
|
||||
|
||||
int dns_getaddr(const char *host, struct in_addr *addr, st_utime_t timeout)
|
||||
{
|
||||
char name[MAXDNAME], **domain;
|
||||
const char *cp;
|
||||
int s, n, maxlen, dots;
|
||||
int trailing_dot, tried_as_is;
|
||||
st_netfd_t nfd;
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return -1;
|
||||
}
|
||||
if (_res.options & RES_USEVC) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
if (!host || *host == '\0') {
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Create UDP socket */
|
||||
if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return -1;
|
||||
}
|
||||
if ((nfd = st_netfd_open_socket(s)) == NULL) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
n = errno;
|
||||
close(s);
|
||||
errno = n;
|
||||
return -1;
|
||||
}
|
||||
|
||||
maxlen = sizeof(name) - 1;
|
||||
n = 0;
|
||||
dots = 0;
|
||||
trailing_dot = 0;
|
||||
tried_as_is = 0;
|
||||
|
||||
for (cp = host; *cp && n < maxlen; cp++) {
|
||||
dots += (*cp == '.');
|
||||
name[n++] = *cp;
|
||||
}
|
||||
if (name[n - 1] == '.')
|
||||
trailing_dot = 1;
|
||||
|
||||
/*
|
||||
* If there are dots in the name already, let's just give it a try
|
||||
* 'as is'. The threshold can be set with the "ndots" option.
|
||||
*/
|
||||
if (dots >= _res.ndots) {
|
||||
if (query_domain(nfd, host, addr, timeout) == 0)
|
||||
CLOSE_AND_RETURN(0);
|
||||
if (h_errno == NETDB_INTERNAL && errno == EINTR)
|
||||
CLOSE_AND_RETURN(-1);
|
||||
tried_as_is = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* We do at least one level of search if
|
||||
* - there is no dot and RES_DEFNAME is set, or
|
||||
* - there is at least one dot, there is no trailing dot,
|
||||
* and RES_DNSRCH is set.
|
||||
*/
|
||||
if ((!dots && (_res.options & RES_DEFNAMES)) ||
|
||||
(dots && !trailing_dot && (_res.options & RES_DNSRCH))) {
|
||||
name[n++] = '.';
|
||||
for (domain = _res.dnsrch; *domain; domain++) {
|
||||
strncpy(name + n, *domain, maxlen - n);
|
||||
if (query_domain(nfd, name, addr, timeout) == 0)
|
||||
CLOSE_AND_RETURN(0);
|
||||
if (h_errno == NETDB_INTERNAL && errno == EINTR)
|
||||
CLOSE_AND_RETURN(-1);
|
||||
if (!(_res.options & RES_DNSRCH))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we have not already tried the name "as is", do that now.
|
||||
* note that we do this regardless of how many dots were in the
|
||||
* name or whether it ends with a dot.
|
||||
*/
|
||||
if (!tried_as_is) {
|
||||
if (query_domain(nfd, host, addr, timeout) == 0)
|
||||
CLOSE_AND_RETURN(0);
|
||||
}
|
||||
|
||||
CLOSE_AND_RETURN(-1);
|
||||
}
|
||||
|
1025
trunk/3rdparty/st-srs/examples/server.c
vendored
Normal file
1025
trunk/3rdparty/st-srs/examples/server.c
vendored
Normal file
File diff suppressed because it is too large
Load diff
91
trunk/3rdparty/st-srs/extensions/Makefile
vendored
Normal file
91
trunk/3rdparty/st-srs/extensions/Makefile
vendored
Normal file
|
@ -0,0 +1,91 @@
|
|||
#
|
||||
# Portions created by SGI are Copyright (C) 2000 Silicon Graphics, Inc.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# 3. Neither the name of Silicon Graphics, Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
CC = cc
|
||||
|
||||
SHELL = /bin/sh
|
||||
ECHO = /bin/echo
|
||||
|
||||
DEPTH = ..
|
||||
BUILD =
|
||||
TARGETDIR = obj
|
||||
|
||||
DEFINES =
|
||||
OTHER_FLAGS =
|
||||
CFLAGS =
|
||||
|
||||
OBJDIR = $(DEPTH)/$(TARGETDIR)
|
||||
INCDIR = $(DEPTH)/$(TARGETDIR)
|
||||
|
||||
LIBRESOLV =
|
||||
EXTRALIBS =
|
||||
|
||||
SLIBRARY = $(OBJDIR)/libstx.a
|
||||
OBJS = $(OBJDIR)/dnscache.o $(OBJDIR)/dnsres.o $(OBJDIR)/lrucache.o
|
||||
|
||||
|
||||
CFLAGS += -Wall -I$(INCDIR)
|
||||
AR = ar
|
||||
ARFLAGS = rv
|
||||
RANLIB = ranlib
|
||||
|
||||
|
||||
##########################
|
||||
# Platform section.
|
||||
#
|
||||
|
||||
ifeq (LINUX, $(findstring LINUX, $(OS)))
|
||||
LIBRESOLV = -lresolv
|
||||
endif
|
||||
|
||||
ifeq ($(OS), SOLARIS)
|
||||
LIBRESOLV = -lresolv
|
||||
EXTRALIBS = -lsocket -lnsl
|
||||
endif
|
||||
|
||||
#
|
||||
# End of platform section.
|
||||
##########################
|
||||
|
||||
|
||||
all: $(SLIBRARY)
|
||||
|
||||
$(SLIBRARY): $(OBJS)
|
||||
$(AR) $(ARFLAGS) $@ $(OBJS)
|
||||
$(RANLIB) $@
|
||||
|
||||
$(OBJDIR)/%.o: %.c stx.h common.h
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
clean:
|
||||
rm -rf $(OBJS) $(SLIBRARY)
|
||||
|
||||
#.DEFAULT:
|
||||
# @cd $(DEPTH); $(MAKE) $@
|
||||
|
42
trunk/3rdparty/st-srs/extensions/README
vendored
Normal file
42
trunk/3rdparty/st-srs/extensions/README
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
This directory contains extensions to the core State Threads Library
|
||||
that were contributed by users. All files hereunder are not part of the
|
||||
State Threads Library itself. They are provided as-is, without warranty
|
||||
or support, and under whatever license terms their authors provided. To
|
||||
contribute your own extensions, just mail them to the project
|
||||
administrators or to one of the project's mailing lists; see
|
||||
state-threads.sourceforge.net. Please indicate the license terms under
|
||||
which the project may distribute your contribution.
|
||||
|
||||
========================================================================
|
||||
|
||||
stx_fileio
|
||||
----------
|
||||
Contributed by Jeff <jlb-st@houseofdistraction.com>, 4 Nov 2002.
|
||||
|
||||
Provides non-blocking random access file reading capability for
|
||||
programs using the State Threads library. There is one public function:
|
||||
|
||||
ssize_t stx_file_read(st_netfd_t fd, off_t offset,
|
||||
void *buf, size_t nbytes, st_utime_t timeout);
|
||||
|
||||
The implementation is not optimal in that the data is copied at least once
|
||||
more than should be necessary. Its usefulness is limited to cases where
|
||||
random access to a file is required and where starvation of other threads
|
||||
is unacceptable.
|
||||
|
||||
The particular application which motivated this implementation was a UDP
|
||||
file transfer protocol. Because the OS does very little buffering of UDP
|
||||
traffic it is important that UDP transmission threads are not starved for
|
||||
periods of time which are long relative to the interval required to
|
||||
maintain a steady send rate.
|
||||
|
||||
Licensed under the same dual MPL/GPL as core State Threads.
|
||||
|
||||
========================================================================
|
||||
|
||||
stx_dns
|
||||
-------
|
||||
|
||||
Documentation coming.
|
||||
|
||||
========================================================================
|
77
trunk/3rdparty/st-srs/extensions/common.h
vendored
Normal file
77
trunk/3rdparty/st-srs/extensions/common.h
vendored
Normal file
|
@ -0,0 +1,77 @@
|
|||
#ifndef _STX_COMMON_H_
|
||||
#define _STX_COMMON_H_
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
#define STX_BEGIN_MACRO {
|
||||
#define STX_END_MACRO }
|
||||
|
||||
|
||||
/*****************************************
|
||||
* Circular linked list definitions
|
||||
*/
|
||||
|
||||
typedef struct _stx_clist {
|
||||
struct _stx_clist *next;
|
||||
struct _stx_clist *prev;
|
||||
} stx_clist_t;
|
||||
|
||||
/* Insert element "_e" into the list, before "_l" */
|
||||
#define STX_CLIST_INSERT_BEFORE(_e,_l) \
|
||||
STX_BEGIN_MACRO \
|
||||
(_e)->next = (_l); \
|
||||
(_e)->prev = (_l)->prev; \
|
||||
(_l)->prev->next = (_e); \
|
||||
(_l)->prev = (_e); \
|
||||
STX_END_MACRO
|
||||
|
||||
/* Insert element "_e" into the list, after "_l" */
|
||||
#define STX_CLIST_INSERT_AFTER(_e,_l) \
|
||||
STX_BEGIN_MACRO \
|
||||
(_e)->next = (_l)->next; \
|
||||
(_e)->prev = (_l); \
|
||||
(_l)->next->prev = (_e); \
|
||||
(_l)->next = (_e); \
|
||||
STX_END_MACRO
|
||||
|
||||
/* Append an element "_e" to the end of the list "_l" */
|
||||
#define STX_CLIST_APPEND_LINK(_e,_l) STX_CLIST_INSERT_BEFORE(_e,_l)
|
||||
|
||||
/* Remove the element "_e" from it's circular list */
|
||||
#define STX_CLIST_REMOVE_LINK(_e) \
|
||||
STX_BEGIN_MACRO \
|
||||
(_e)->prev->next = (_e)->next; \
|
||||
(_e)->next->prev = (_e)->prev; \
|
||||
STX_END_MACRO
|
||||
|
||||
/* Return the head/tail of the list */
|
||||
#define STX_CLIST_HEAD(_l) (_l)->next
|
||||
#define STX_CLIST_TAIL(_l) (_l)->prev
|
||||
|
||||
/* Return non-zero if the given circular list "_l" is empty, */
|
||||
/* zero if the circular list is not empty */
|
||||
#define STX_CLIST_IS_EMPTY(_l) \
|
||||
((_l)->next == (_l))
|
||||
|
||||
/* Initialize a circular list */
|
||||
#define STX_CLIST_INIT_CLIST(_l) \
|
||||
STX_BEGIN_MACRO \
|
||||
(_l)->next = (_l); \
|
||||
(_l)->prev = (_l); \
|
||||
STX_END_MACRO
|
||||
|
||||
|
||||
/*****************************************
|
||||
* Useful macros
|
||||
*/
|
||||
|
||||
#ifndef offsetof
|
||||
#define offsetof(type, identifier) ((size_t)&(((type *)0)->identifier))
|
||||
#endif
|
||||
|
||||
#define STX_MIN(a, b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
#endif /* !_STX_COMMON_H_ */
|
||||
|
190
trunk/3rdparty/st-srs/extensions/dnscache.c
vendored
Normal file
190
trunk/3rdparty/st-srs/extensions/dnscache.c
vendored
Normal file
|
@ -0,0 +1,190 @@
|
|||
#include "stx.h"
|
||||
#include "common.h"
|
||||
|
||||
|
||||
/*****************************************
|
||||
* Basic types definitions
|
||||
*/
|
||||
|
||||
typedef struct _stx_dns_data {
|
||||
struct in_addr *addrs;
|
||||
int num_addrs;
|
||||
int cur;
|
||||
time_t expires;
|
||||
} stx_dns_data_t;
|
||||
|
||||
|
||||
#define MAX_HOST_ADDRS 1024
|
||||
|
||||
static struct in_addr addr_list[MAX_HOST_ADDRS];
|
||||
|
||||
stx_cache_t *_stx_dns_cache = NULL;
|
||||
|
||||
extern int _stx_dns_ttl;
|
||||
extern int _stx_dns_getaddrlist(const char *hostname, struct in_addr *addrs,
|
||||
int *num_addrs, st_utime_t timeout);
|
||||
|
||||
|
||||
static unsigned long hash_hostname(const void *key)
|
||||
{
|
||||
const char *name = (const char *)key;
|
||||
unsigned long hash = 0;
|
||||
|
||||
while (*name)
|
||||
hash = (hash << 4) - hash + *name++; /* hash = hash * 15 + *name++ */
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
static void cleanup_entry(void *key, void *data)
|
||||
{
|
||||
if (key)
|
||||
free(key);
|
||||
|
||||
if (data) {
|
||||
if (((stx_dns_data_t *)data)->addrs)
|
||||
free(((stx_dns_data_t *)data)->addrs);
|
||||
free(data);
|
||||
}
|
||||
}
|
||||
|
||||
static int lookup_entry(const char *host, struct in_addr *addrs,
|
||||
int *num_addrs, int rotate)
|
||||
{
|
||||
stx_cache_entry_t *entry;
|
||||
stx_dns_data_t *data;
|
||||
int n;
|
||||
|
||||
entry = stx_cache_entry_lookup(_stx_dns_cache, host);
|
||||
if (entry) {
|
||||
data = (stx_dns_data_t *)stx_cache_entry_getdata(entry);
|
||||
if (st_time() <= data->expires) {
|
||||
if (*num_addrs == 1) {
|
||||
if (rotate) {
|
||||
*addrs = data->addrs[data->cur++];
|
||||
if (data->cur >= data->num_addrs)
|
||||
data->cur = 0;
|
||||
} else {
|
||||
*addrs = data->addrs[0];
|
||||
}
|
||||
} else {
|
||||
n = STX_MIN(*num_addrs, data->num_addrs);
|
||||
memcpy(addrs, data->addrs, n * sizeof(*addrs));
|
||||
*num_addrs = n;
|
||||
}
|
||||
|
||||
stx_cache_entry_release(_stx_dns_cache, entry);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Cache entry expired: decrement its refcount and purge it from cache.
|
||||
*/
|
||||
stx_cache_entry_release(_stx_dns_cache, entry);
|
||||
stx_cache_entry_delete(_stx_dns_cache, entry);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void insert_entry(const char *host, struct in_addr *addrs, int count)
|
||||
{
|
||||
stx_cache_entry_t *entry;
|
||||
stx_dns_data_t *data;
|
||||
char *key;
|
||||
size_t n;
|
||||
|
||||
if (_stx_dns_ttl > 0) {
|
||||
key = strdup(host);
|
||||
data = (stx_dns_data_t *)malloc(sizeof(stx_dns_data_t));
|
||||
n = count * sizeof(*addrs);
|
||||
if (data) {
|
||||
data->addrs = (struct in_addr *)malloc(n);
|
||||
if (data->addrs)
|
||||
memcpy(data->addrs, addrs, n);
|
||||
data->num_addrs = count;
|
||||
data->cur = 0;
|
||||
data->expires = st_time() + _stx_dns_ttl;
|
||||
}
|
||||
entry = stx_cache_entry_create(key, data, strlen(host) + 1 +
|
||||
sizeof(stx_dns_data_t) + n +
|
||||
stx_cache_entry_sizeof());
|
||||
if (key && data && data->addrs && entry &&
|
||||
stx_cache_entry_insert(_stx_dns_cache, entry) == 0) {
|
||||
stx_cache_entry_release(_stx_dns_cache, entry);
|
||||
return;
|
||||
}
|
||||
|
||||
if (entry)
|
||||
stx_cache_entry_delete(_stx_dns_cache, entry);
|
||||
else
|
||||
cleanup_entry(key, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
int _stx_dns_cache_getaddrlist(const char *hostname, struct in_addr *addrs,
|
||||
int *num_addrs, st_utime_t timeout,
|
||||
int rotate)
|
||||
{
|
||||
char host[128];
|
||||
int n, count;
|
||||
|
||||
if (!_stx_dns_cache)
|
||||
return _stx_dns_getaddrlist(hostname, addrs, num_addrs, timeout);
|
||||
|
||||
for (n = 0; n < sizeof(host) - 1 && hostname[n]; n++) {
|
||||
host[n] = tolower(hostname[n]);
|
||||
}
|
||||
host[n] = '\0';
|
||||
|
||||
if (lookup_entry(host, addrs, num_addrs, rotate))
|
||||
return 0;
|
||||
|
||||
count = MAX_HOST_ADDRS;
|
||||
if (_stx_dns_getaddrlist(host, addr_list, &count, timeout) < 0)
|
||||
return -1;
|
||||
n = STX_MIN(*num_addrs, count);
|
||||
memcpy(addrs, addr_list, n * sizeof(*addrs));
|
||||
*num_addrs = n;
|
||||
|
||||
insert_entry(host, addr_list, count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int stx_dns_cache_init(size_t max_size, size_t max_bytes, size_t hash_size)
|
||||
{
|
||||
_stx_dns_cache = stx_cache_create(max_size, max_bytes, hash_size,
|
||||
hash_hostname,
|
||||
(long (*)(const void *, const void *))strcmp,
|
||||
cleanup_entry);
|
||||
if (!_stx_dns_cache)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void stx_dns_cache_getinfo(stx_cache_info_t *info)
|
||||
{
|
||||
if (_stx_dns_cache)
|
||||
stx_cache_getinfo(_stx_dns_cache, info);
|
||||
else
|
||||
memset(info, 0, sizeof(stx_cache_info_t));
|
||||
}
|
||||
|
||||
int stx_dns_getaddrlist(const char *hostname, struct in_addr *addrs,
|
||||
int *num_addrs, st_utime_t timeout)
|
||||
{
|
||||
return _stx_dns_cache_getaddrlist(hostname, addrs, num_addrs, timeout, 0);
|
||||
}
|
||||
|
||||
int stx_dns_getaddr(const char *hostname, struct in_addr *addr,
|
||||
st_utime_t timeout)
|
||||
{
|
||||
int n = 1;
|
||||
|
||||
return _stx_dns_cache_getaddrlist(hostname, addr, &n, timeout, 1);
|
||||
}
|
||||
|
305
trunk/3rdparty/st-srs/extensions/dnsres.c
vendored
Normal file
305
trunk/3rdparty/st-srs/extensions/dnsres.c
vendored
Normal file
|
@ -0,0 +1,305 @@
|
|||
/*
|
||||
* Copyright (c) 1985, 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Portions created by SGI are Copyright (C) 2000 Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of Silicon Graphics, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "stx.h"
|
||||
|
||||
#define MAXPACKET 1024
|
||||
|
||||
#if !defined(NETDB_INTERNAL) && defined(h_NETDB_INTERNAL)
|
||||
#define NETDB_INTERNAL h_NETDB_INTERNAL
|
||||
#endif
|
||||
|
||||
/* New in Solaris 7 */
|
||||
#if !defined(_getshort) && defined(ns_get16)
|
||||
#define _getshort(cp) ns_get16(cp)
|
||||
#define _getlong(cp) ns_get32(cp)
|
||||
#endif
|
||||
|
||||
typedef union {
|
||||
HEADER hdr;
|
||||
u_char buf[MAXPACKET];
|
||||
} querybuf_t;
|
||||
|
||||
int _stx_dns_ttl;
|
||||
|
||||
|
||||
static int parse_answer(querybuf_t *ans, int len, struct in_addr *addrs,
|
||||
int *num_addrs)
|
||||
{
|
||||
char buf[MAXPACKET];
|
||||
HEADER *ahp;
|
||||
u_char *cp, *eoa;
|
||||
int type, n, i;
|
||||
|
||||
ahp = &ans->hdr;
|
||||
eoa = ans->buf + len;
|
||||
cp = ans->buf + sizeof(HEADER);
|
||||
h_errno = TRY_AGAIN;
|
||||
_stx_dns_ttl = -1;
|
||||
i = 0;
|
||||
|
||||
while (ahp->qdcount > 0) {
|
||||
ahp->qdcount--;
|
||||
cp += dn_skipname(cp, eoa) + QFIXEDSZ;
|
||||
}
|
||||
while (ahp->ancount > 0 && cp < eoa && i < *num_addrs) {
|
||||
ahp->ancount--;
|
||||
if ((n = dn_expand(ans->buf, eoa, cp, buf, sizeof(buf))) < 0)
|
||||
return -1;
|
||||
cp += n;
|
||||
if (cp + 4 + 4 + 2 >= eoa)
|
||||
return -1;
|
||||
type = _getshort(cp);
|
||||
cp += 4;
|
||||
if (type == T_A)
|
||||
_stx_dns_ttl = _getlong(cp);
|
||||
cp += 4;
|
||||
n = _getshort(cp);
|
||||
cp += 2;
|
||||
if (type == T_A) {
|
||||
if (n > sizeof(*addrs) || cp + n > eoa)
|
||||
return -1;
|
||||
memcpy(&addrs[i++], cp, n);
|
||||
}
|
||||
cp += n;
|
||||
}
|
||||
|
||||
*num_addrs = i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int query_domain(st_netfd_t nfd, const char *name,
|
||||
struct in_addr *addrs, int *num_addrs,
|
||||
st_utime_t timeout)
|
||||
{
|
||||
querybuf_t qbuf;
|
||||
u_char *buf = qbuf.buf;
|
||||
HEADER *hp = &qbuf.hdr;
|
||||
int blen = sizeof(qbuf);
|
||||
int i, len, id;
|
||||
|
||||
for (i = 0; i < _res.nscount; i++) {
|
||||
len = res_mkquery(QUERY, name, C_IN, T_A, NULL, 0, NULL, buf, blen);
|
||||
if (len <= 0) {
|
||||
h_errno = NO_RECOVERY;
|
||||
return -1;
|
||||
}
|
||||
id = hp->id;
|
||||
|
||||
if (st_sendto(nfd, buf, len, (struct sockaddr *)&(_res.nsaddr_list[i]),
|
||||
sizeof(struct sockaddr), timeout) != len) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
/* EINTR means interrupt by other thread, NOT by a caught signal */
|
||||
if (errno == EINTR)
|
||||
return -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Wait for reply */
|
||||
do {
|
||||
len = st_recvfrom(nfd, buf, blen, NULL, NULL, timeout);
|
||||
if (len <= 0)
|
||||
break;
|
||||
} while (id != hp->id);
|
||||
|
||||
if (len < HFIXEDSZ) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
if (len >= 0)
|
||||
errno = EMSGSIZE;
|
||||
else if (errno == EINTR) /* see the comment above */
|
||||
return -1;
|
||||
continue;
|
||||
}
|
||||
|
||||
hp->ancount = ntohs(hp->ancount);
|
||||
hp->qdcount = ntohs(hp->qdcount);
|
||||
if ((hp->rcode != NOERROR) || (hp->ancount == 0)) {
|
||||
switch (hp->rcode) {
|
||||
case NXDOMAIN:
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
break;
|
||||
case SERVFAIL:
|
||||
h_errno = TRY_AGAIN;
|
||||
break;
|
||||
case NOERROR:
|
||||
h_errno = NO_DATA;
|
||||
break;
|
||||
case FORMERR:
|
||||
case NOTIMP:
|
||||
case REFUSED:
|
||||
default:
|
||||
h_errno = NO_RECOVERY;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (parse_answer(&qbuf, len, addrs, num_addrs) == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
#define CLOSE_AND_RETURN(ret) \
|
||||
{ \
|
||||
n = errno; \
|
||||
st_netfd_close(nfd); \
|
||||
errno = n; \
|
||||
return (ret); \
|
||||
}
|
||||
|
||||
|
||||
int _stx_dns_getaddrlist(const char *host, struct in_addr *addrs,
|
||||
int *num_addrs, st_utime_t timeout)
|
||||
{
|
||||
char name[MAXDNAME], **domain;
|
||||
const char *cp;
|
||||
int s, n, maxlen, dots;
|
||||
int trailing_dot, tried_as_is;
|
||||
st_netfd_t nfd;
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return -1;
|
||||
}
|
||||
if (_res.options & RES_USEVC) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
if (!host || *host == '\0') {
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Create UDP socket */
|
||||
if ((s = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return -1;
|
||||
}
|
||||
if ((nfd = st_netfd_open_socket(s)) == NULL) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
n = errno;
|
||||
close(s);
|
||||
errno = n;
|
||||
return -1;
|
||||
}
|
||||
|
||||
maxlen = sizeof(name) - 1;
|
||||
n = 0;
|
||||
dots = 0;
|
||||
trailing_dot = 0;
|
||||
tried_as_is = 0;
|
||||
|
||||
for (cp = host; *cp && n < maxlen; cp++) {
|
||||
dots += (*cp == '.');
|
||||
name[n++] = *cp;
|
||||
}
|
||||
if (name[n - 1] == '.')
|
||||
trailing_dot = 1;
|
||||
|
||||
/*
|
||||
* If there are dots in the name already, let's just give it a try
|
||||
* 'as is'. The threshold can be set with the "ndots" option.
|
||||
*/
|
||||
if (dots >= _res.ndots) {
|
||||
if (query_domain(nfd, host, addrs, num_addrs, timeout) == 0)
|
||||
CLOSE_AND_RETURN(0);
|
||||
if (h_errno == NETDB_INTERNAL && errno == EINTR)
|
||||
CLOSE_AND_RETURN(-1);
|
||||
tried_as_is = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* We do at least one level of search if
|
||||
* - there is no dot and RES_DEFNAME is set, or
|
||||
* - there is at least one dot, there is no trailing dot,
|
||||
* and RES_DNSRCH is set.
|
||||
*/
|
||||
if ((!dots && (_res.options & RES_DEFNAMES)) ||
|
||||
(dots && !trailing_dot && (_res.options & RES_DNSRCH))) {
|
||||
name[n++] = '.';
|
||||
for (domain = _res.dnsrch; *domain; domain++) {
|
||||
strncpy(name + n, *domain, maxlen - n);
|
||||
if (query_domain(nfd, name, addrs, num_addrs, timeout) == 0)
|
||||
CLOSE_AND_RETURN(0);
|
||||
if (h_errno == NETDB_INTERNAL && errno == EINTR)
|
||||
CLOSE_AND_RETURN(-1);
|
||||
if (!(_res.options & RES_DNSRCH))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we have not already tried the name "as is", do that now.
|
||||
* note that we do this regardless of how many dots were in the
|
||||
* name or whether it ends with a dot.
|
||||
*/
|
||||
if (!tried_as_is) {
|
||||
if (query_domain(nfd, host, addrs, num_addrs, timeout) == 0)
|
||||
CLOSE_AND_RETURN(0);
|
||||
}
|
||||
|
||||
CLOSE_AND_RETURN(-1);
|
||||
}
|
||||
|
343
trunk/3rdparty/st-srs/extensions/lrucache.c
vendored
Normal file
343
trunk/3rdparty/st-srs/extensions/lrucache.c
vendored
Normal file
|
@ -0,0 +1,343 @@
|
|||
#include "stx.h"
|
||||
#include "common.h"
|
||||
|
||||
|
||||
/*****************************************
|
||||
* Basic types definitions
|
||||
*/
|
||||
|
||||
struct _stx_centry {
|
||||
void *key; /* key for doing lookups */
|
||||
void *data; /* data in the cache */
|
||||
size_t weight; /* "weight" of this entry */
|
||||
struct _stx_centry *next; /* next entry */
|
||||
struct _stx_centry **pthis;
|
||||
stx_clist_t lru_link; /* for putting this entry on LRU list */
|
||||
int ref_count; /* use count for this entry */
|
||||
int delete_pending; /* pending delete flag */
|
||||
};
|
||||
|
||||
struct _stx_cache {
|
||||
size_t max_size; /* max size of cache */
|
||||
size_t cur_size; /* current size of cache */
|
||||
|
||||
size_t max_weight; /* cache capacity */
|
||||
size_t cur_weight; /* current total "weight" of all entries */
|
||||
|
||||
size_t hash_size; /* size of hash table */
|
||||
stx_cache_entry_t **table; /* hash table for this cache */
|
||||
|
||||
stx_clist_t lru_list; /* least-recently-used list */
|
||||
|
||||
/* Cache stats */
|
||||
unsigned long hits; /* num cache hits */
|
||||
unsigned long lookups; /* num cache lookups */
|
||||
unsigned long inserts; /* num inserts */
|
||||
unsigned long deletes; /* num deletes */
|
||||
|
||||
/* Functions */
|
||||
unsigned long (*key_hash_fn)(const void *);
|
||||
long (*key_cmp_fn)(const void *, const void *);
|
||||
void (*cleanup_fn)(void *, void *);
|
||||
};
|
||||
|
||||
|
||||
#define STX_CACHE_ENTRY_PTR(_qp) \
|
||||
((stx_cache_entry_t *)((char *)(_qp) - offsetof(stx_cache_entry_t, lru_link)))
|
||||
|
||||
|
||||
/*****************************************
|
||||
* Cache methods
|
||||
*/
|
||||
|
||||
stx_cache_t *stx_cache_create(size_t max_size, size_t max_weight,
|
||||
size_t hash_size,
|
||||
unsigned long (*key_hash_fn)(const void *key),
|
||||
long (*key_cmp_fn)(const void *key1,
|
||||
const void *key2),
|
||||
void (*cleanup_fn)(void *key, void *data))
|
||||
{
|
||||
stx_cache_t *newcache;
|
||||
|
||||
newcache = (stx_cache_t *)calloc(1, sizeof(stx_cache_t));
|
||||
if (newcache == NULL)
|
||||
return NULL;
|
||||
newcache->table = (stx_cache_entry_t **)calloc(hash_size,
|
||||
sizeof(stx_cache_entry_t *));
|
||||
if (newcache->table == NULL) {
|
||||
free(newcache);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
newcache->max_size = max_size;
|
||||
newcache->max_weight = max_weight;
|
||||
newcache->hash_size = hash_size;
|
||||
STX_CLIST_INIT_CLIST(&(newcache->lru_list));
|
||||
newcache->key_hash_fn = key_hash_fn;
|
||||
newcache->key_cmp_fn = key_cmp_fn;
|
||||
newcache->cleanup_fn = cleanup_fn;
|
||||
|
||||
return newcache;
|
||||
}
|
||||
|
||||
|
||||
void stx_cache_empty(stx_cache_t *cache)
|
||||
{
|
||||
size_t i;
|
||||
stx_cache_entry_t *entry, *next_entry;
|
||||
|
||||
for (i = 0; i < cache->hash_size; i++) {
|
||||
entry = cache->table[i];
|
||||
while (entry) {
|
||||
next_entry = entry->next;
|
||||
stx_cache_entry_delete(cache, entry);
|
||||
entry = next_entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void stx_cache_traverse(stx_cache_t *cache,
|
||||
void (*callback)(void *key, void *data))
|
||||
{
|
||||
size_t i;
|
||||
stx_cache_entry_t *entry;
|
||||
|
||||
for (i = 0; i < cache->hash_size; i++) {
|
||||
for (entry = cache->table[i]; entry; entry = entry->next) {
|
||||
if (!entry->delete_pending)
|
||||
(*callback)(entry->key, entry->data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void stx_cache_traverse_lru(stx_cache_t *cache,
|
||||
void (*callback)(void *key, void *data),
|
||||
unsigned int n)
|
||||
{
|
||||
stx_clist_t *q;
|
||||
stx_cache_entry_t *entry;
|
||||
|
||||
for (q = STX_CLIST_HEAD(&cache->lru_list); q != &cache->lru_list && n;
|
||||
q = q->next, n--) {
|
||||
entry = STX_CACHE_ENTRY_PTR(q);
|
||||
(*callback)(entry->key, entry->data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void stx_cache_traverse_mru(stx_cache_t *cache,
|
||||
void (*callback)(void *key, void *data),
|
||||
unsigned int n)
|
||||
{
|
||||
stx_clist_t *q;
|
||||
stx_cache_entry_t *entry;
|
||||
|
||||
for (q = STX_CLIST_TAIL(&cache->lru_list); q != &cache->lru_list && n;
|
||||
q = q->prev, n--) {
|
||||
entry = STX_CACHE_ENTRY_PTR(q);
|
||||
(*callback)(entry->key, entry->data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
size_t stx_cache_getsize(stx_cache_t *cache)
|
||||
{
|
||||
return cache->cur_size;
|
||||
}
|
||||
|
||||
|
||||
size_t stx_cache_getweight(stx_cache_t *cache)
|
||||
{
|
||||
return cache->cur_weight;
|
||||
}
|
||||
|
||||
|
||||
void stx_cache_getinfo(stx_cache_t *cache, stx_cache_info_t *info)
|
||||
{
|
||||
info->max_size = cache->max_size;
|
||||
info->max_weight = cache->max_weight;
|
||||
info->hash_size = cache->hash_size;
|
||||
info->cur_size = cache->cur_size;
|
||||
info->cur_weight = cache->cur_weight;
|
||||
info->hits = cache->hits;
|
||||
info->lookups = cache->lookups;
|
||||
info->inserts = cache->inserts;
|
||||
info->deletes = cache->deletes;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************
|
||||
* Cache entry methods
|
||||
*/
|
||||
|
||||
stx_cache_entry_t *stx_cache_entry_create(void *key, void *data,
|
||||
size_t weight)
|
||||
{
|
||||
stx_cache_entry_t *newentry;
|
||||
|
||||
newentry = (stx_cache_entry_t *)calloc(1, sizeof(stx_cache_entry_t));
|
||||
if (newentry == NULL)
|
||||
return NULL;
|
||||
|
||||
newentry->key = key;
|
||||
newentry->data = data;
|
||||
newentry->weight = weight;
|
||||
|
||||
return newentry;
|
||||
}
|
||||
|
||||
|
||||
void stx_cache_entry_delete(stx_cache_t *cache, stx_cache_entry_t *entry)
|
||||
{
|
||||
entry->delete_pending = 1;
|
||||
|
||||
if (entry->ref_count > 0)
|
||||
return;
|
||||
|
||||
if (entry->pthis) {
|
||||
*entry->pthis = entry->next;
|
||||
if (entry->next)
|
||||
entry->next->pthis = entry->pthis;
|
||||
|
||||
cache->cur_size--;
|
||||
cache->cur_weight -= entry->weight;
|
||||
cache->deletes++;
|
||||
STX_CLIST_REMOVE_LINK(&(entry->lru_link));
|
||||
}
|
||||
|
||||
if (cache->cleanup_fn)
|
||||
cache->cleanup_fn(entry->key, entry->data);
|
||||
|
||||
entry->pthis = NULL;
|
||||
entry->key = NULL;
|
||||
entry->data = NULL;
|
||||
free(entry);
|
||||
}
|
||||
|
||||
|
||||
stx_cache_entry_t *stx_cache_entry_lookup(stx_cache_t *cache, const void *key)
|
||||
{
|
||||
unsigned long bucket;
|
||||
stx_cache_entry_t *entry;
|
||||
|
||||
cache->lookups++;
|
||||
bucket = cache->key_hash_fn(key) % cache->hash_size;
|
||||
for (entry = cache->table[bucket]; entry; entry = entry->next) {
|
||||
if (!entry->delete_pending && cache->key_cmp_fn(key, entry->key) == 0)
|
||||
break;
|
||||
}
|
||||
if (entry) {
|
||||
cache->hits++;
|
||||
if (entry->ref_count == 0)
|
||||
STX_CLIST_REMOVE_LINK(&(entry->lru_link));
|
||||
entry->ref_count++;
|
||||
}
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
||||
void stx_cache_entry_release(stx_cache_t *cache, stx_cache_entry_t *entry)
|
||||
{
|
||||
if (entry->ref_count == 0)
|
||||
return;
|
||||
|
||||
entry->ref_count--;
|
||||
|
||||
if (entry->ref_count == 0) {
|
||||
STX_CLIST_APPEND_LINK(&(entry->lru_link), &(cache->lru_list));
|
||||
if (entry->delete_pending)
|
||||
stx_cache_entry_delete(cache, entry);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int stx_cache_entry_insert(stx_cache_t *cache, stx_cache_entry_t *entry)
|
||||
{
|
||||
stx_cache_entry_t *old_entry;
|
||||
unsigned long bucket;
|
||||
|
||||
/*
|
||||
* If cache capacity is exceeded, try to remove LRU entries till there is
|
||||
* enough room or LRU list is empty.
|
||||
*/
|
||||
while (cache->cur_weight + entry->weight > cache->max_weight) {
|
||||
old_entry = stx_cache_entry_getlru(cache);
|
||||
if (!old_entry) {
|
||||
/* cache capacity is exceeded and all entries are in use */
|
||||
return -1;
|
||||
}
|
||||
stx_cache_entry_delete(cache, old_entry);
|
||||
}
|
||||
|
||||
/* If cache size is exceeded, remove LRU entry */
|
||||
if (cache->cur_size >= cache->max_size) {
|
||||
old_entry = stx_cache_entry_getlru(cache);
|
||||
if (!old_entry) {
|
||||
/* cache size is exceeded and all entries are in use */
|
||||
return -1;
|
||||
}
|
||||
stx_cache_entry_delete(cache, old_entry);
|
||||
}
|
||||
|
||||
/* Don't add duplicate entries in the cache */
|
||||
bucket = cache->key_hash_fn(entry->key) % cache->hash_size;
|
||||
for (old_entry = cache->table[bucket]; old_entry;
|
||||
old_entry = old_entry->next) {
|
||||
if (!old_entry->delete_pending &&
|
||||
cache->key_cmp_fn(entry->key, old_entry->key) == 0)
|
||||
break;
|
||||
}
|
||||
if (old_entry)
|
||||
stx_cache_entry_delete(cache, old_entry);
|
||||
|
||||
/* Insert in the hash table */
|
||||
entry->next = cache->table[bucket];
|
||||
cache->table[bucket] = entry;
|
||||
entry->pthis = &cache->table[bucket];
|
||||
if (entry->next)
|
||||
entry->next->pthis = &entry->next;
|
||||
entry->ref_count++;
|
||||
|
||||
cache->inserts++;
|
||||
cache->cur_size++;
|
||||
cache->cur_weight += entry->weight;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
stx_cache_entry_t *stx_cache_entry_getlru(stx_cache_t *cache)
|
||||
{
|
||||
if (STX_CLIST_IS_EMPTY(&(cache->lru_list)))
|
||||
return NULL;
|
||||
|
||||
return STX_CACHE_ENTRY_PTR(STX_CLIST_HEAD(&(cache->lru_list)));
|
||||
}
|
||||
|
||||
|
||||
int stx_cache_entry_sizeof(void)
|
||||
{
|
||||
return (int)sizeof(stx_cache_entry_t);
|
||||
}
|
||||
|
||||
|
||||
void *stx_cache_entry_getdata(stx_cache_entry_t *entry)
|
||||
{
|
||||
return entry->data;
|
||||
}
|
||||
|
||||
|
||||
void *stx_cache_entry_getkey(stx_cache_entry_t *entry)
|
||||
{
|
||||
return entry->key;
|
||||
}
|
||||
|
||||
|
||||
size_t stx_cache_entry_getweight(stx_cache_entry_t *entry)
|
||||
{
|
||||
return entry->weight;
|
||||
}
|
||||
|
367
trunk/3rdparty/st-srs/extensions/print_stk.patch
vendored
Normal file
367
trunk/3rdparty/st-srs/extensions/print_stk.patch
vendored
Normal file
|
@ -0,0 +1,367 @@
|
|||
Michael Abd-El-Malek contributed this patch. He wrote:
|
||||
----------------------------------------
|
||||
Hello,
|
||||
|
||||
This is a patch that enables programmatically dumping the stack of
|
||||
every thread. This has been useful in debugging deadlocks, etc...
|
||||
Our usage model is that the SIGUSR2 handler calls the new
|
||||
_st_print_thread_stacks function, which dumps the stack for all
|
||||
threads. A convenient feature is that for thread stacks that are the
|
||||
same (which is common for application with a lot of worker threads
|
||||
waiting for work), only one stack trace is printed, along with a
|
||||
count of how many threads have that same stack.
|
||||
|
||||
I use the glibc backtrace function to get the backtrace, and then use
|
||||
popen to execute addr2line and convert memory addresses to file
|
||||
names, function names, and line numbers. If glibc isn't available,
|
||||
_st_print_thread_stacks just prints a warning. And this feature is
|
||||
only available if DEBUG is turned on.
|
||||
|
||||
We've found this feature extremely helpful when debugging.
|
||||
|
||||
The patch can be a bit more robust (it assumes addr2line exists).
|
||||
But I didn't want to go through the hassle of doing this, if the
|
||||
StateThreads community doesn't want to use this patch. (In our
|
||||
environment, addr2line will always be there.)
|
||||
|
||||
Cheers,
|
||||
Mike
|
||||
----------------------------------------
|
||||
Invoking complex functions from a signal handler is not recommended,
|
||||
plus this patch changes the behavior of existing API hooks. It will
|
||||
not become part of State Threads proper but you may find it useful
|
||||
nonetheless. This patch applies to st-1.5.2.
|
||||
|
||||
diff -Nur Makefile.1.5.2 Makefile
|
||||
--- Makefile.1.5.2 Wed Sep 7 14:19:50 2005
|
||||
+++ Makefile Wed Sep 7 14:33:08 2005
|
||||
@@ -255,7 +255,8 @@
|
||||
$(TARGETDIR)/stk.o \
|
||||
$(TARGETDIR)/sync.o \
|
||||
$(TARGETDIR)/key.o \
|
||||
- $(TARGETDIR)/io.o
|
||||
+ $(TARGETDIR)/io.o \
|
||||
+ $(TARGETDIR)/backtrace.o
|
||||
OBJS += $(EXTRA_OBJS)
|
||||
HEADER = $(TARGETDIR)/st.h
|
||||
SLIBRARY = $(TARGETDIR)/libst.a
|
||||
diff -Nur backtrace.c.1.5.2 backtrace.c
|
||||
--- backtrace.c.1.5.2 Wed Dec 31 16:00:00 1969
|
||||
+++ backtrace.c Wed Sep 7 13:40:21 2005
|
||||
@@ -0,0 +1,211 @@
|
||||
+/*
|
||||
+ * The contents of this file are subject to the Mozilla Public
|
||||
+ * License Version 1.1 (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.mozilla.org/MPL/
|
||||
+ *
|
||||
+ * Software distributed under the License is distributed on an "AS
|
||||
+ * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
+ * implied. See the License for the specific language governing
|
||||
+ * rights and limitations under the License.
|
||||
+ *
|
||||
+ * Contributor(s): Michael Abd-El-Malek (mabdelmalek@cmu.edu)
|
||||
+ * Carnegie Mellon University
|
||||
+ *
|
||||
+ * Alternatively, the contents of this file may be used under the
|
||||
+ * terms of the GNU General Public License Version 2 or later (the
|
||||
+ * "GPL"), in which case the provisions of the GPL are applicable
|
||||
+ * instead of those above. If you wish to allow use of your
|
||||
+ * version of this file only under the terms of the GPL and not to
|
||||
+ * allow others to use your version of this file under the MPL,
|
||||
+ * indicate your decision by deleting the provisions above and
|
||||
+ * replace them with the notice and other provisions required by
|
||||
+ * the GPL. If you do not delete the provisions above, a recipient
|
||||
+ * may use your version of this file under either the MPL or the
|
||||
+ * GPL.
|
||||
+ */
|
||||
+
|
||||
+
|
||||
+
|
||||
+/*
|
||||
+ * This file contains routines for printing a stack trace of all threads.
|
||||
+ * Only works when DEBUG is defined and where glibc is available, since it
|
||||
+ * provides the backtrace() function.
|
||||
+ */
|
||||
+
|
||||
+#define _GNU_SOURCE /* to get program_invocation_name */
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+
|
||||
+
|
||||
+#if defined(DEBUG) && defined(__GLIBC__)
|
||||
+
|
||||
+#include <errno.h>
|
||||
+#include "common.h"
|
||||
+#include <execinfo.h>
|
||||
+#include <inttypes.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+
|
||||
+/* The maximum number of frames to get a stack trace for. If a thread has more
|
||||
+ * frames than this, then we only show the latest X frames. */
|
||||
+#define MAX_NUM_FRAMES 64
|
||||
+
|
||||
+
|
||||
+typedef struct thread_stack_s {
|
||||
+ uint32_t num_frames;
|
||||
+ void* addresses[MAX_NUM_FRAMES]; /* frame pointers */
|
||||
+ char* locations[MAX_NUM_FRAMES]; /* file/function/line numbers */
|
||||
+ uint32_t num_matches;
|
||||
+
|
||||
+ struct thread_stack_s* next;
|
||||
+} thread_stack_t;
|
||||
+
|
||||
+static thread_stack_t* stacks = NULL;
|
||||
+
|
||||
+
|
||||
+/* Converts the function's memory addresses to function names, file names, and
|
||||
+ * line numbers. Calls binutil's addr2line program. */
|
||||
+static void get_symbol_names(thread_stack_t *stack)
|
||||
+{
|
||||
+ char program_to_run[1024], function[256], filename_lineno[256], temp[19];
|
||||
+ FILE* output;
|
||||
+ int num_bytes_left;
|
||||
+ uint32_t i;
|
||||
+
|
||||
+ /* Construct the arguments to addr2line */
|
||||
+ num_bytes_left = sizeof(program_to_run);
|
||||
+ num_bytes_left -= snprintf(program_to_run, sizeof(program_to_run),
|
||||
+ "addr2line -fCe %s", program_invocation_name);
|
||||
+ for (i = 0; i < stack->num_frames && num_bytes_left > 0; ++i) {
|
||||
+ num_bytes_left -= snprintf(temp, sizeof(temp), " %p", stack->addresses[i]);
|
||||
+ strncat(program_to_run, temp, num_bytes_left);
|
||||
+ }
|
||||
+
|
||||
+ /* Use popen to execute addr2line and read its ouput */
|
||||
+ output = popen(program_to_run, "r");
|
||||
+ for (i = 0; i < stack->num_frames; ++i) {
|
||||
+ char* function_listing = (char*) malloc(512);
|
||||
+ fscanf(output, "%255s\n", function);
|
||||
+ fscanf(output, "%255s\n", filename_lineno);
|
||||
+ snprintf(function_listing, 512, "%s at %s", function, filename_lineno);
|
||||
+ stack->locations[i] = function_listing;
|
||||
+ }
|
||||
+ pclose(output);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static void print_stack(thread_stack_t* stack)
|
||||
+{
|
||||
+ int skip_offset = 0, cmp_len;
|
||||
+ uint32_t i;
|
||||
+
|
||||
+ /* Get the function names/filenames/line numbers */
|
||||
+ get_symbol_names(stack);
|
||||
+
|
||||
+ cmp_len = strlen("_st_iterate_threads_helper");
|
||||
+
|
||||
+ /* Print the backtrace */
|
||||
+ for (i = 0; i < stack->num_frames; ++i) {
|
||||
+ /* Skip frames we don't have location info for */
|
||||
+ if (!strncmp(stack->locations[i], "??", 2)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ /* Skip the frames that are used for printing the stack trace */
|
||||
+ if (skip_offset) {
|
||||
+ printf("\t#%2d %s %p\n", i - skip_offset, stack->locations[i],
|
||||
+ stack->addresses[i]);
|
||||
+ } else if (!strncmp(stack->locations[i], "_st_iterate_threads_helper",
|
||||
+ cmp_len)) {
|
||||
+ skip_offset = i + 1;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static void add_current_thread_stack(void)
|
||||
+{
|
||||
+ thread_stack_t *new_stack = malloc(sizeof(thread_stack_t));
|
||||
+ thread_stack_t *search;
|
||||
+
|
||||
+ /* Call glibc function to get the backtrace */
|
||||
+ new_stack->num_frames = backtrace(new_stack->addresses, MAX_NUM_FRAMES);
|
||||
+
|
||||
+ /* Check if we have another stacks that is equivalent. If so, then coaelsce
|
||||
+ * two stacks into one, to minimize output to user. */
|
||||
+ search = stacks;
|
||||
+ while (search) {
|
||||
+ if (search->num_frames == new_stack->num_frames &&
|
||||
+ !memcmp(search->addresses, new_stack->addresses,
|
||||
+ search->num_frames * sizeof(void*))) {
|
||||
+ /* Found an existing stack that is the same as this thread's stack */
|
||||
+ ++search->num_matches;
|
||||
+ free(new_stack);
|
||||
+ return;
|
||||
+ } else {
|
||||
+ search = search->next;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /* This is a new stack. Add it to the list of stacks. */
|
||||
+ new_stack->num_matches = 1;
|
||||
+ new_stack->next = stacks;
|
||||
+ stacks = new_stack;
|
||||
+}
|
||||
+
|
||||
+static void print_stack_frames(void)
|
||||
+{
|
||||
+ while (stacks) {
|
||||
+ printf("\n%u thread(s) with this backtrace:\n", stacks->num_matches);
|
||||
+ print_stack(stacks);
|
||||
+ stacks = stacks->next;
|
||||
+ }
|
||||
+ printf("\n");
|
||||
+}
|
||||
+
|
||||
+static void free_stacks(void)
|
||||
+{
|
||||
+ uint32_t i;
|
||||
+ while (stacks) {
|
||||
+ thread_stack_t *next = stacks->next;
|
||||
+ for (i = 0; i < stacks->num_frames; ++i) {
|
||||
+ free(stacks->locations[i]);
|
||||
+ }
|
||||
+ free(stacks);
|
||||
+ stacks = next;
|
||||
+ }
|
||||
+ stacks = NULL;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static void st_print_thread_stack(_st_thread_t *thread, int start_flag,
|
||||
+ int end_flag)
|
||||
+{
|
||||
+ if (end_flag == 0) {
|
||||
+ add_current_thread_stack();
|
||||
+ } else {
|
||||
+ print_stack_frames();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
+void _st_print_thread_stacks(int ignore)
|
||||
+{
|
||||
+ _st_iterate_threads_flag = 1;
|
||||
+ _st_iterate_threads_helper(st_print_thread_stack);
|
||||
+ _st_iterate_threads_flag = 0;
|
||||
+
|
||||
+ /* Deallocate memory */
|
||||
+ free_stacks();
|
||||
+}
|
||||
+
|
||||
+#else /* defined(DEBUG) && defined(__GLIBC__) */
|
||||
+
|
||||
+void _st_print_thread_stacks(int ignore)
|
||||
+{
|
||||
+ printf("%s: need DEBUG mode and glibc-specific functions to read stack.\n",
|
||||
+ __FUNCTION__);
|
||||
+}
|
||||
+#endif /* defined(DEBUG) && defined(__GLIBC__) */
|
||||
diff -Nur common.h.1.5.2 common.h
|
||||
--- common.h.1.5.2 Wed Sep 7 14:18:37 2005
|
||||
+++ common.h Wed Sep 7 14:35:36 2005
|
||||
@@ -371,8 +371,18 @@
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
-void _st_iterate_threads(void);
|
||||
-#define ST_DEBUG_ITERATE_THREADS() _st_iterate_threads()
|
||||
+typedef void(*_st_func_ptr_t)(_st_thread_t *thread,
|
||||
+ int start_flag,
|
||||
+ int end_flag);
|
||||
+/* Pointer to function that will be called on thread switch */
|
||||
+extern _st_func_ptr_t _st_iterate_func_ptr;
|
||||
+extern int _st_iterate_threads_flag;
|
||||
+/* Thread iteration function that will call an arbitrary function */
|
||||
+extern void _st_iterate_threads_helper(_st_func_ptr_t func);
|
||||
+#define ST_DEBUG_ITERATE_THREADS() \
|
||||
+ if (_st_iterate_func_ptr) { \
|
||||
+ _st_iterate_threads_helper(_st_iterate_func_ptr); \
|
||||
+ }
|
||||
#else
|
||||
#define ST_DEBUG_ITERATE_THREADS()
|
||||
#endif
|
||||
diff -Nur public.h.1.5.2 public.h
|
||||
--- public.h.1.5.2 Wed Sep 7 11:46:58 2005
|
||||
+++ public.h Wed Sep 7 13:38:46 2005
|
||||
@@ -171,8 +171,10 @@
|
||||
extern st_netfd_t st_open(const char *path, int oflags, mode_t mode);
|
||||
|
||||
#ifdef DEBUG
|
||||
-extern void _st_show_thread_stack(st_thread_t thread, const char *messg);
|
||||
+extern void _st_show_thread_stack(st_thread_t thread, int start_flag,
|
||||
+ int end_flag);
|
||||
extern void _st_iterate_threads(void);
|
||||
+extern void _st_print_thread_stacks(int ignore);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
diff -Nur sched.c.1.5.2 sched.c
|
||||
--- sched.c.1.5.2 Wed Sep 7 10:48:05 2005
|
||||
+++ sched.c Wed Sep 7 13:38:46 2005
|
||||
@@ -919,16 +919,13 @@
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
-/* ARGSUSED */
|
||||
-void _st_show_thread_stack(_st_thread_t *thread, const char *messg)
|
||||
-{
|
||||
-
|
||||
-}
|
||||
-
|
||||
/* To be set from debugger */
|
||||
int _st_iterate_threads_flag = 0;
|
||||
+/* Thread iteration function that will call an arbitrary function */
|
||||
+_st_func_ptr_t _st_iterate_func_ptr = NULL;
|
||||
|
||||
-void _st_iterate_threads(void)
|
||||
+/* This function iterates over all threads, calling "func" for each thread. */
|
||||
+void _st_iterate_threads_helper(_st_func_ptr_t func)
|
||||
{
|
||||
static _st_thread_t *thread = NULL;
|
||||
static jmp_buf orig_jb, save_jb;
|
||||
@@ -944,16 +941,20 @@
|
||||
|
||||
if (thread) {
|
||||
memcpy(thread->context, save_jb, sizeof(jmp_buf));
|
||||
- _st_show_thread_stack(thread, NULL);
|
||||
+ func(thread, 0, 0);
|
||||
} else {
|
||||
if (MD_SETJMP(orig_jb)) {
|
||||
_st_iterate_threads_flag = 0;
|
||||
+ _st_iterate_func_ptr = NULL;
|
||||
thread = NULL;
|
||||
- _st_show_thread_stack(thread, "Iteration completed");
|
||||
+ /* Last thread to iterate through */
|
||||
+ func(thread, 0, 1);
|
||||
return;
|
||||
}
|
||||
+ /* First thread to iterate through */
|
||||
thread = _ST_CURRENT_THREAD();
|
||||
- _st_show_thread_stack(thread, "Iteration started");
|
||||
+ _st_iterate_func_ptr = func;
|
||||
+ func(thread, 1, 0);
|
||||
}
|
||||
|
||||
q = thread->tlink.next;
|
||||
@@ -966,5 +967,17 @@
|
||||
memcpy(save_jb, thread->context, sizeof(jmp_buf));
|
||||
MD_LONGJMP(thread->context, 1);
|
||||
}
|
||||
+
|
||||
+/* ARGSUSED */
|
||||
+void _st_show_thread_stack(_st_thread_t *thread, int start_flag, int end_flag)
|
||||
+{
|
||||
+}
|
||||
+
|
||||
+/* Iterate over threads inside debugger; see st/README */
|
||||
+void _st_iterate_threads(void)
|
||||
+{
|
||||
+ _st_iterate_threads_helper(_st_show_thread_stack);
|
||||
+}
|
||||
+
|
||||
#endif /* DEBUG */
|
||||
|
91
trunk/3rdparty/st-srs/extensions/stx.h
vendored
Normal file
91
trunk/3rdparty/st-srs/extensions/stx.h
vendored
Normal file
|
@ -0,0 +1,91 @@
|
|||
#ifndef _STX_H_
|
||||
#define _STX_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <resolv.h>
|
||||
#include <netdb.h>
|
||||
#include <errno.h>
|
||||
#include "st.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/*****************************************
|
||||
* Basic types definitions
|
||||
*/
|
||||
|
||||
typedef struct _stx_centry stx_cache_entry_t;
|
||||
typedef struct _stx_cache stx_cache_t;
|
||||
|
||||
/* This is public type */
|
||||
typedef struct _stx_cache_info {
|
||||
size_t max_size;
|
||||
size_t max_weight;
|
||||
size_t hash_size;
|
||||
size_t cur_size;
|
||||
size_t cur_weight;
|
||||
unsigned long hits;
|
||||
unsigned long lookups;
|
||||
unsigned long inserts;
|
||||
unsigned long deletes;
|
||||
} stx_cache_info_t;
|
||||
|
||||
|
||||
/*****************************************
|
||||
* Cache and cache entry methods
|
||||
*/
|
||||
|
||||
stx_cache_t *stx_cache_create(size_t max_size, size_t max_weight,
|
||||
size_t hash_size,
|
||||
unsigned long (*key_hash_fn)(const void *key),
|
||||
long (*key_cmp_fn)(const void *key1,
|
||||
const void *key2),
|
||||
void (*cleanup_fn)(void *key, void *data));
|
||||
void stx_cache_empty(stx_cache_t *cache);
|
||||
void stx_cache_traverse(stx_cache_t *cache,
|
||||
void (*callback)(void *key, void *data));
|
||||
void stx_cache_traverse_lru(stx_cache_t *, void (*)(void *, void *),
|
||||
unsigned int);
|
||||
void stx_cache_traverse_mru(stx_cache_t *, void (*)(void *, void *),
|
||||
unsigned int);
|
||||
void stx_cache_getinfo(stx_cache_t *cache, stx_cache_info_t *info);
|
||||
size_t stx_cache_getsize(stx_cache_t *cache);
|
||||
size_t stx_cache_getweight(stx_cache_t *cache);
|
||||
|
||||
|
||||
stx_cache_entry_t *stx_cache_entry_create(void *key, void *data,
|
||||
size_t weight);
|
||||
void stx_cache_entry_delete(stx_cache_t *cache, stx_cache_entry_t *entry);
|
||||
stx_cache_entry_t *stx_cache_entry_lookup(stx_cache_t *cache, const void *key);
|
||||
void stx_cache_entry_release(stx_cache_t *, stx_cache_entry_t *);
|
||||
int stx_cache_entry_insert(stx_cache_t *cache, stx_cache_entry_t *entry);
|
||||
stx_cache_entry_t *stx_cache_entry_getlru(stx_cache_t *cache);
|
||||
int stx_cache_entry_sizeof(void);
|
||||
void *stx_cache_entry_getdata(stx_cache_entry_t *entry);
|
||||
void *stx_cache_entry_getkey(stx_cache_entry_t *entry);
|
||||
size_t stx_cache_entry_getweight(stx_cache_entry_t *entry);
|
||||
|
||||
|
||||
int stx_dns_cache_init(size_t max_size, size_t max_bytes, size_t hash_size);
|
||||
void stx_dns_cache_getinfo(stx_cache_info_t *info);
|
||||
int stx_dns_getaddrlist(const char *hostname, struct in_addr *addrs,
|
||||
int *num_addrs, st_utime_t timeout);
|
||||
int stx_dns_getaddr(const char *hostname, struct in_addr *addr,
|
||||
st_utime_t timeout);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !_STX_H_ */
|
||||
|
197
trunk/3rdparty/st-srs/extensions/stx_fileio.c
vendored
Normal file
197
trunk/3rdparty/st-srs/extensions/stx_fileio.c
vendored
Normal file
|
@ -0,0 +1,197 @@
|
|||
/*
|
||||
* File I/O extension to the State Threads Library.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the file I/O extension to the State Threads Library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Jeff
|
||||
* <jlb-st@houseofdistraction.com>. Portions created by the Initial
|
||||
* Developer are Copyright (C) 2002 the Initial Developer. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* Contributor(s): (none)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "stx_fileio.h"
|
||||
|
||||
#define STX_FILEIO_SIGNUM SIGUSR2
|
||||
|
||||
typedef struct {
|
||||
st_netfd_t data_fd;
|
||||
st_netfd_t control_fd;
|
||||
pid_t pid;
|
||||
} fileio_data_t;
|
||||
|
||||
#define FILEREADER_MAX_READ 1024
|
||||
|
||||
typedef struct {
|
||||
off_t offset;
|
||||
ssize_t nbytes;
|
||||
} file_reader_cb_t;
|
||||
|
||||
/**
|
||||
* Fork a process to read a file and return its pid. Receives
|
||||
* offset/length commands from control stream and sends corresponding data
|
||||
* to out stream. A zero length on the control stream signals an end.
|
||||
*
|
||||
* @param fd stream from which to read
|
||||
* @param control_out receives the file descriptor to which control commands can be sent
|
||||
* @param fd_out receives the file descriptor from which the output of the command can be read.
|
||||
* @return PID of the process created to execute the command
|
||||
*/
|
||||
pid_t
|
||||
file_reader(int fd, int *fd_control, int *fd_out)
|
||||
{
|
||||
pid_t pid;
|
||||
int control_pipe[2], out_pipe[2];
|
||||
|
||||
if (pipe(control_pipe) < 0 || pipe(out_pipe) < 0)
|
||||
return (pid_t)-1;
|
||||
|
||||
pid = fork();
|
||||
if (pid == (pid_t) -1)
|
||||
{
|
||||
close(control_pipe[0]);
|
||||
close(control_pipe[1]);
|
||||
close(out_pipe[0]);
|
||||
close(out_pipe[1]);
|
||||
return pid;
|
||||
}
|
||||
else if (pid == (pid_t) 0)
|
||||
{
|
||||
// child
|
||||
off_t pos = 0;
|
||||
file_reader_cb_t cb;
|
||||
char buf[FILEREADER_MAX_READ];
|
||||
if (fd == -1)
|
||||
_exit(EXIT_FAILURE);
|
||||
|
||||
while (sizeof(cb) == read(control_pipe[0], &cb, sizeof(cb))) {
|
||||
ssize_t nb;
|
||||
if (0 >= cb.nbytes)
|
||||
goto clean_exit;
|
||||
if (pos != cb.offset) {
|
||||
pos = lseek(fd, cb.offset, SEEK_SET);
|
||||
if (pos == (off_t)-1)
|
||||
break;
|
||||
}
|
||||
nb = read(fd, buf, cb.nbytes);
|
||||
if (nb == (ssize_t)-1)
|
||||
break;
|
||||
pos += nb;
|
||||
write(out_pipe[1], (char *)&nb, sizeof(nb));
|
||||
write(out_pipe[1], buf, nb);
|
||||
}
|
||||
perror("ERROR: file_reader: ");
|
||||
clean_exit:
|
||||
close(control_pipe[0]);
|
||||
close(control_pipe[1]);
|
||||
close(out_pipe[0]);
|
||||
close(out_pipe[1]);
|
||||
_exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
// parent
|
||||
close(out_pipe[1]);
|
||||
close(control_pipe[0]);
|
||||
*fd_out = out_pipe[0];
|
||||
*fd_control = control_pipe[1];
|
||||
return pid;
|
||||
}
|
||||
|
||||
/**
|
||||
* fileio_data_t destructor callback
|
||||
*/
|
||||
static void
|
||||
fileio_data_destructor(void *dat_in)
|
||||
{
|
||||
if (dat_in) {
|
||||
fileio_data_t *dat = (fileio_data_t *)dat_in;
|
||||
file_reader_cb_t cb;
|
||||
cb.offset = 0;
|
||||
cb.nbytes = 0;
|
||||
st_write(dat->control_fd, (char *)&cb, sizeof(cb),
|
||||
ST_UTIME_NO_TIMEOUT);
|
||||
waitpid(dat->pid, NULL, 0);
|
||||
st_netfd_close(dat->control_fd);
|
||||
st_netfd_close(dat->data_fd);
|
||||
free(dat_in);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve fileio_data_t struct from an st descriptor. Create and store
|
||||
* a new one if needed.
|
||||
*/
|
||||
static fileio_data_t *get_fileio_data(st_netfd_t fd)
|
||||
{
|
||||
fileio_data_t *dat = (fileio_data_t *)st_netfd_getspecific(fd);
|
||||
if (!dat) {
|
||||
int fd_control, fd_out;
|
||||
pid_t pid = file_reader(st_netfd_fileno(fd), &fd_control, &fd_out);
|
||||
if (pid != (pid_t)-1) {
|
||||
dat = (fileio_data_t *)calloc(1, sizeof(fileio_data_t));
|
||||
dat->control_fd = st_netfd_open(fd_control);
|
||||
dat->data_fd = st_netfd_open(fd_out);
|
||||
dat->pid = pid;
|
||||
st_netfd_setspecific(fd, dat, fileio_data_destructor);
|
||||
}
|
||||
}
|
||||
return dat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read data from the specified section of a file. Uses a forked
|
||||
* file_reader process to do the actual reading so as to avoid causing all
|
||||
* State Threads to block.
|
||||
*
|
||||
* @param fd must refer to a seekable file.
|
||||
* @param offset absolute offset within the file
|
||||
* @param buf output buffer
|
||||
* @param nbytes size of the output buffer
|
||||
* @param timeout
|
||||
*/
|
||||
ssize_t
|
||||
stx_file_read(st_netfd_t fd, off_t offset, void *buf, size_t nbytes, st_utime_t timeout)
|
||||
{
|
||||
fileio_data_t *dat = get_fileio_data(fd);
|
||||
if (dat) {
|
||||
file_reader_cb_t cb;
|
||||
ssize_t ret = (ssize_t)-1;
|
||||
cb.offset = offset;
|
||||
cb.nbytes = nbytes;
|
||||
st_write(dat->control_fd, (char *)&cb, sizeof(cb), timeout);
|
||||
if (sizeof(ret) == st_read(dat->data_fd, (char *)&ret, sizeof(ret), timeout) && 0 < ret && ret <= nbytes) {
|
||||
return st_read(dat->data_fd, buf, ret, timeout);
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return (ssize_t)-1;
|
||||
}
|
52
trunk/3rdparty/st-srs/extensions/stx_fileio.h
vendored
Normal file
52
trunk/3rdparty/st-srs/extensions/stx_fileio.h
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* File I/O extension to the State Threads Library.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the file I/O extension to the State Threads Library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Jeff
|
||||
* <jlb-st@houseofdistraction.com>. Portions created by the Initial
|
||||
* Developer are Copyright (C) 2002 the Initial Developer. All Rights
|
||||
* Reserved.
|
||||
*
|
||||
* Contributor(s): (none)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
#ifndef __STX_FILEIO_H__
|
||||
#define __STX_FILEIO_H__
|
||||
|
||||
#include <st.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern ssize_t stx_file_read(st_netfd_t fd, off_t offset, void *buf, size_t nbytes, st_utime_t timeout);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !__STX_FILEIO_H__ */
|
112
trunk/3rdparty/st-srs/extensions/testdns.c
vendored
Normal file
112
trunk/3rdparty/st-srs/extensions/testdns.c
vendored
Normal file
|
@ -0,0 +1,112 @@
|
|||
#include "stx.h"
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
|
||||
#define MAX_ADDRS 128
|
||||
#define TIMEOUT (4*1000000LL)
|
||||
|
||||
static void do_resolve(const char *host)
|
||||
{
|
||||
struct in_addr addrs[MAX_ADDRS];
|
||||
int i, n = MAX_ADDRS;
|
||||
|
||||
if (stx_dns_getaddrlist(host, addrs, &n, TIMEOUT) < 0) {
|
||||
fprintf(stderr, "stx_dns_getaddrlist: can't resolve %s: ", host);
|
||||
if (h_errno == NETDB_INTERNAL)
|
||||
perror("");
|
||||
else
|
||||
herror("");
|
||||
} else {
|
||||
if (n > 0)
|
||||
printf("%-40s %s\n", (char *)host, inet_ntoa(addrs[0]));
|
||||
for (i = 1; i < n; i++)
|
||||
printf("%-40s %s\n", "", inet_ntoa(addrs[i]));
|
||||
}
|
||||
}
|
||||
|
||||
static void show_info(void)
|
||||
{
|
||||
stx_cache_info_t info;
|
||||
|
||||
stx_dns_cache_getinfo(&info);
|
||||
printf("DNS cache info:\n\n");
|
||||
printf("max_size: %8d\n", (int)info.max_size);
|
||||
printf("capacity: %8d bytes\n", (int)info.max_weight);
|
||||
printf("hash_size: %8d\n", (int)info.hash_size);
|
||||
printf("cur_size: %8d\n"
|
||||
"cur_mem: %8d bytes\n"
|
||||
"hits: %8d\n"
|
||||
"lookups: %8d\n"
|
||||
"inserts: %8d\n"
|
||||
"deletes: %8d\n",
|
||||
(int)info.cur_size, (int)info.cur_weight, (int)info.hits,
|
||||
(int)info.lookups, (int)info.inserts, (int)info.deletes);
|
||||
}
|
||||
|
||||
extern stx_cache_t *_stx_dns_cache;
|
||||
|
||||
static void printhost(void *host, void *data)
|
||||
{
|
||||
printf("%s\n", (char *)host);
|
||||
}
|
||||
|
||||
static void show_lru(void)
|
||||
{
|
||||
printf("LRU hosts:\n\n");
|
||||
stx_cache_traverse_lru(_stx_dns_cache, printhost, 10);
|
||||
}
|
||||
|
||||
static void show_mru(void)
|
||||
{
|
||||
printf("MRU hosts:\n\n");
|
||||
stx_cache_traverse_mru(_stx_dns_cache, printhost, 10);
|
||||
}
|
||||
|
||||
static void flush_cache(void)
|
||||
{
|
||||
stx_cache_empty(_stx_dns_cache);
|
||||
printf("DNS cache is empty\n");
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
char line[256];
|
||||
char str[sizeof(line)];
|
||||
|
||||
st_init();
|
||||
stx_dns_cache_init(100, 10000, 101);
|
||||
|
||||
for ( ; ; ) {
|
||||
fputs("> ", stdout);
|
||||
fflush(stdout);
|
||||
if (!fgets(line, sizeof(line), stdin))
|
||||
break;
|
||||
if (sscanf(line, "%s", str) != 1)
|
||||
continue;
|
||||
if (strcmp(str, "exit") == 0 || strcmp(str, "quit") == 0)
|
||||
break;
|
||||
if (strcmp(str, "info") == 0) {
|
||||
show_info();
|
||||
continue;
|
||||
}
|
||||
if (strcmp(str, "lru") == 0) {
|
||||
show_lru();
|
||||
continue;
|
||||
}
|
||||
if (strcmp(str, "mru") == 0) {
|
||||
show_mru();
|
||||
continue;
|
||||
}
|
||||
if (strcmp(str, "flush") == 0) {
|
||||
flush_cache();
|
||||
continue;
|
||||
}
|
||||
|
||||
do_resolve(str);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
769
trunk/3rdparty/st-srs/io.c
vendored
Normal file
769
trunk/3rdparty/st-srs/io.c
vendored
Normal file
|
@ -0,0 +1,769 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape Portable Runtime library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Silicon Graphics, Inc.
|
||||
*
|
||||
* Portions created by SGI are Copyright (C) 2000-2001 Silicon
|
||||
* Graphics, Inc. All Rights Reserved.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is derived directly from Netscape Communications Corporation,
|
||||
* and consists of extensive modifications made during the year(s) 1999-2000.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include "common.h"
|
||||
|
||||
|
||||
#if EAGAIN != EWOULDBLOCK
|
||||
#define _IO_NOT_READY_ERROR ((errno == EAGAIN) || (errno == EWOULDBLOCK))
|
||||
#else
|
||||
#define _IO_NOT_READY_ERROR (errno == EAGAIN)
|
||||
#endif
|
||||
|
||||
#define _LOCAL_MAXIOV 16
|
||||
|
||||
/* File descriptor object free list */
|
||||
static _st_netfd_t *_st_netfd_freelist = NULL;
|
||||
/* Maximum number of file descriptors that the process can open */
|
||||
static int _st_osfd_limit = -1;
|
||||
|
||||
static void _st_netfd_free_aux_data(_st_netfd_t *fd);
|
||||
|
||||
int _st_io_init(void)
|
||||
{
|
||||
struct sigaction sigact;
|
||||
struct rlimit rlim;
|
||||
int fdlim;
|
||||
|
||||
/* Ignore SIGPIPE */
|
||||
sigact.sa_handler = SIG_IGN;
|
||||
sigemptyset(&sigact.sa_mask);
|
||||
sigact.sa_flags = 0;
|
||||
if (sigaction(SIGPIPE, &sigact, NULL) < 0)
|
||||
return -1;
|
||||
|
||||
/* Set maximum number of open file descriptors */
|
||||
if (getrlimit(RLIMIT_NOFILE, &rlim) < 0)
|
||||
return -1;
|
||||
|
||||
fdlim = (*_st_eventsys->fd_getlimit)();
|
||||
if (fdlim > 0 && rlim.rlim_max > (rlim_t) fdlim) {
|
||||
rlim.rlim_max = fdlim;
|
||||
}
|
||||
|
||||
/**
|
||||
* by SRS, for osx.
|
||||
* when rlimit max is negative, for example, osx, use cur directly.
|
||||
* @see https://github.com/winlinvip/simple-rtmp-server/issues/336
|
||||
*/
|
||||
if ((int)rlim.rlim_max < 0) {
|
||||
_st_osfd_limit = (int)(fdlim > 0? fdlim : rlim.rlim_cur);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rlim.rlim_cur = rlim.rlim_max;
|
||||
if (setrlimit(RLIMIT_NOFILE, &rlim) < 0)
|
||||
return -1;
|
||||
_st_osfd_limit = (int) rlim.rlim_max;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int st_getfdlimit(void)
|
||||
{
|
||||
return _st_osfd_limit;
|
||||
}
|
||||
|
||||
|
||||
void st_netfd_free(_st_netfd_t *fd)
|
||||
{
|
||||
if (!fd->inuse)
|
||||
return;
|
||||
|
||||
fd->inuse = 0;
|
||||
if (fd->aux_data)
|
||||
_st_netfd_free_aux_data(fd);
|
||||
if (fd->private_data && fd->destructor)
|
||||
(*(fd->destructor))(fd->private_data);
|
||||
fd->private_data = NULL;
|
||||
fd->destructor = NULL;
|
||||
fd->next = _st_netfd_freelist;
|
||||
_st_netfd_freelist = fd;
|
||||
}
|
||||
|
||||
|
||||
static _st_netfd_t *_st_netfd_new(int osfd, int nonblock, int is_socket)
|
||||
{
|
||||
_st_netfd_t *fd;
|
||||
int flags = 1;
|
||||
|
||||
if ((*_st_eventsys->fd_new)(osfd) < 0)
|
||||
return NULL;
|
||||
|
||||
if (_st_netfd_freelist) {
|
||||
fd = _st_netfd_freelist;
|
||||
_st_netfd_freelist = _st_netfd_freelist->next;
|
||||
} else {
|
||||
fd = calloc(1, sizeof(_st_netfd_t));
|
||||
if (!fd)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fd->osfd = osfd;
|
||||
fd->inuse = 1;
|
||||
fd->next = NULL;
|
||||
|
||||
if (nonblock) {
|
||||
/* Use just one system call */
|
||||
if (is_socket && ioctl(osfd, FIONBIO, &flags) != -1)
|
||||
return fd;
|
||||
/* Do it the Posix way */
|
||||
if ((flags = fcntl(osfd, F_GETFL, 0)) < 0 ||
|
||||
fcntl(osfd, F_SETFL, flags | O_NONBLOCK) < 0) {
|
||||
st_netfd_free(fd);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
_st_netfd_t *st_netfd_open(int osfd)
|
||||
{
|
||||
return _st_netfd_new(osfd, 1, 0);
|
||||
}
|
||||
|
||||
|
||||
_st_netfd_t *st_netfd_open_socket(int osfd)
|
||||
{
|
||||
return _st_netfd_new(osfd, 1, 1);
|
||||
}
|
||||
|
||||
|
||||
int st_netfd_close(_st_netfd_t *fd)
|
||||
{
|
||||
if ((*_st_eventsys->fd_close)(fd->osfd) < 0)
|
||||
return -1;
|
||||
|
||||
st_netfd_free(fd);
|
||||
return close(fd->osfd);
|
||||
}
|
||||
|
||||
|
||||
int st_netfd_fileno(_st_netfd_t *fd)
|
||||
{
|
||||
return (fd->osfd);
|
||||
}
|
||||
|
||||
|
||||
void st_netfd_setspecific(_st_netfd_t *fd, void *value, _st_destructor_t destructor)
|
||||
{
|
||||
if (value != fd->private_data) {
|
||||
/* Free up previously set non-NULL data value */
|
||||
if (fd->private_data && fd->destructor)
|
||||
(*(fd->destructor))(fd->private_data);
|
||||
}
|
||||
fd->private_data = value;
|
||||
fd->destructor = destructor;
|
||||
}
|
||||
|
||||
|
||||
void *st_netfd_getspecific(_st_netfd_t *fd)
|
||||
{
|
||||
return (fd->private_data);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Wait for I/O on a single descriptor.
|
||||
*/
|
||||
int st_netfd_poll(_st_netfd_t *fd, int how, st_utime_t timeout)
|
||||
{
|
||||
struct pollfd pd;
|
||||
int n;
|
||||
|
||||
pd.fd = fd->osfd;
|
||||
pd.events = (short) how;
|
||||
pd.revents = 0;
|
||||
|
||||
if ((n = st_poll(&pd, 1, timeout)) < 0)
|
||||
return -1;
|
||||
if (n == 0) {
|
||||
/* Timed out */
|
||||
errno = ETIME;
|
||||
return -1;
|
||||
}
|
||||
if (pd.revents & POLLNVAL) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef MD_ALWAYS_UNSERIALIZED_ACCEPT
|
||||
/* No-op */
|
||||
int st_netfd_serialize_accept(_st_netfd_t *fd)
|
||||
{
|
||||
fd->aux_data = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* No-op */
|
||||
static void _st_netfd_free_aux_data(_st_netfd_t *fd)
|
||||
{
|
||||
fd->aux_data = NULL;
|
||||
}
|
||||
|
||||
_st_netfd_t *st_accept(_st_netfd_t *fd, struct sockaddr *addr, int *addrlen, st_utime_t timeout)
|
||||
{
|
||||
int osfd, err;
|
||||
_st_netfd_t *newfd;
|
||||
|
||||
while ((osfd = accept(fd->osfd, addr, (socklen_t *)addrlen)) < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
if (!_IO_NOT_READY_ERROR)
|
||||
return NULL;
|
||||
/* Wait until the socket becomes readable */
|
||||
if (st_netfd_poll(fd, POLLIN, timeout) < 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* On some platforms the new socket created by accept() inherits */
|
||||
/* the nonblocking attribute of the listening socket */
|
||||
#if defined (MD_ACCEPT_NB_INHERITED)
|
||||
newfd = _st_netfd_new(osfd, 0, 1);
|
||||
#elif defined (MD_ACCEPT_NB_NOT_INHERITED)
|
||||
newfd = _st_netfd_new(osfd, 1, 1);
|
||||
#else
|
||||
#error Unknown OS
|
||||
#endif
|
||||
|
||||
if (!newfd) {
|
||||
err = errno;
|
||||
close(osfd);
|
||||
errno = err;
|
||||
}
|
||||
|
||||
return newfd;
|
||||
}
|
||||
|
||||
#else /* MD_ALWAYS_UNSERIALIZED_ACCEPT */
|
||||
/*
|
||||
* On some platforms accept() calls from different processes
|
||||
* on the same listen socket must be serialized.
|
||||
* The following code serializes accept()'s without process blocking.
|
||||
* A pipe is used as an inter-process semaphore.
|
||||
*/
|
||||
int st_netfd_serialize_accept(_st_netfd_t *fd)
|
||||
{
|
||||
_st_netfd_t **p;
|
||||
int osfd[2], err;
|
||||
|
||||
if (fd->aux_data) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if ((p = (_st_netfd_t **)calloc(2, sizeof(_st_netfd_t *))) == NULL)
|
||||
return -1;
|
||||
if (pipe(osfd) < 0) {
|
||||
free(p);
|
||||
return -1;
|
||||
}
|
||||
if ((p[0] = st_netfd_open(osfd[0])) != NULL && (p[1] = st_netfd_open(osfd[1])) != NULL && write(osfd[1], " ", 1) == 1) {
|
||||
fd->aux_data = p;
|
||||
return 0;
|
||||
}
|
||||
/* Error */
|
||||
err = errno;
|
||||
if (p[0])
|
||||
st_netfd_free(p[0]);
|
||||
if (p[1])
|
||||
st_netfd_free(p[1]);
|
||||
close(osfd[0]);
|
||||
close(osfd[1]);
|
||||
free(p);
|
||||
errno = err;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void _st_netfd_free_aux_data(_st_netfd_t *fd)
|
||||
{
|
||||
_st_netfd_t **p = (_st_netfd_t **) fd->aux_data;
|
||||
|
||||
st_netfd_close(p[0]);
|
||||
st_netfd_close(p[1]);
|
||||
free(p);
|
||||
fd->aux_data = NULL;
|
||||
}
|
||||
|
||||
_st_netfd_t *st_accept(_st_netfd_t *fd, struct sockaddr *addr, int *addrlen, st_utime_t timeout)
|
||||
{
|
||||
int osfd, err;
|
||||
_st_netfd_t *newfd;
|
||||
_st_netfd_t **p = (_st_netfd_t **) fd->aux_data;
|
||||
ssize_t n;
|
||||
char c;
|
||||
|
||||
for ( ; ; ) {
|
||||
if (p == NULL) {
|
||||
osfd = accept(fd->osfd, addr, (socklen_t *)addrlen);
|
||||
} else {
|
||||
/* Get the lock */
|
||||
n = st_read(p[0], &c, 1, timeout);
|
||||
if (n < 0)
|
||||
return NULL;
|
||||
ST_ASSERT(n == 1);
|
||||
/* Got the lock */
|
||||
osfd = accept(fd->osfd, addr, (socklen_t *)addrlen);
|
||||
/* Unlock */
|
||||
err = errno;
|
||||
n = st_write(p[1], &c, 1, timeout);
|
||||
ST_ASSERT(n == 1);
|
||||
errno = err;
|
||||
}
|
||||
if (osfd >= 0)
|
||||
break;
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
if (!_IO_NOT_READY_ERROR)
|
||||
return NULL;
|
||||
/* Wait until the socket becomes readable */
|
||||
if (st_netfd_poll(fd, POLLIN, timeout) < 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* On some platforms the new socket created by accept() inherits */
|
||||
/* the nonblocking attribute of the listening socket */
|
||||
#if defined (MD_ACCEPT_NB_INHERITED)
|
||||
newfd = _st_netfd_new(osfd, 0, 1);
|
||||
#elif defined (MD_ACCEPT_NB_NOT_INHERITED)
|
||||
newfd = _st_netfd_new(osfd, 1, 1);
|
||||
#else
|
||||
#error Unknown OS
|
||||
#endif
|
||||
|
||||
if (!newfd) {
|
||||
err = errno;
|
||||
close(osfd);
|
||||
errno = err;
|
||||
}
|
||||
|
||||
return newfd;
|
||||
}
|
||||
#endif /* MD_ALWAYS_UNSERIALIZED_ACCEPT */
|
||||
|
||||
|
||||
int st_connect(_st_netfd_t *fd, const struct sockaddr *addr, int addrlen, st_utime_t timeout)
|
||||
{
|
||||
int n, err = 0;
|
||||
|
||||
while (connect(fd->osfd, addr, addrlen) < 0) {
|
||||
if (errno != EINTR) {
|
||||
/*
|
||||
* On some platforms, if connect() is interrupted (errno == EINTR)
|
||||
* after the kernel binds the socket, a subsequent connect()
|
||||
* attempt will fail with errno == EADDRINUSE. Ignore EADDRINUSE
|
||||
* iff connect() was previously interrupted. See Rich Stevens'
|
||||
* "UNIX Network Programming," Vol. 1, 2nd edition, p. 413
|
||||
* ("Interrupted connect").
|
||||
*/
|
||||
if (errno != EINPROGRESS && (errno != EADDRINUSE || err == 0))
|
||||
return -1;
|
||||
/* Wait until the socket becomes writable */
|
||||
if (st_netfd_poll(fd, POLLOUT, timeout) < 0)
|
||||
return -1;
|
||||
/* Try to find out whether the connection setup succeeded or failed */
|
||||
n = sizeof(int);
|
||||
if (getsockopt(fd->osfd, SOL_SOCKET, SO_ERROR, (char *)&err, (socklen_t *)&n) < 0)
|
||||
return -1;
|
||||
if (err) {
|
||||
errno = err;
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
err = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
ssize_t st_read(_st_netfd_t *fd, void *buf, size_t nbyte, st_utime_t timeout)
|
||||
{
|
||||
ssize_t n;
|
||||
|
||||
while ((n = read(fd->osfd, buf, nbyte)) < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
if (!_IO_NOT_READY_ERROR)
|
||||
return -1;
|
||||
/* Wait until the socket becomes readable */
|
||||
if (st_netfd_poll(fd, POLLIN, timeout) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
int st_read_resid(_st_netfd_t *fd, void *buf, size_t *resid, st_utime_t timeout)
|
||||
{
|
||||
struct iovec iov, *riov;
|
||||
int riov_size, rv;
|
||||
|
||||
iov.iov_base = buf;
|
||||
iov.iov_len = *resid;
|
||||
riov = &iov;
|
||||
riov_size = 1;
|
||||
rv = st_readv_resid(fd, &riov, &riov_size, timeout);
|
||||
*resid = iov.iov_len;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
ssize_t st_readv(_st_netfd_t *fd, const struct iovec *iov, int iov_size, st_utime_t timeout)
|
||||
{
|
||||
ssize_t n;
|
||||
|
||||
while ((n = readv(fd->osfd, iov, iov_size)) < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
if (!_IO_NOT_READY_ERROR)
|
||||
return -1;
|
||||
/* Wait until the socket becomes readable */
|
||||
if (st_netfd_poll(fd, POLLIN, timeout) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int st_readv_resid(_st_netfd_t *fd, struct iovec **iov, int *iov_size, st_utime_t timeout)
|
||||
{
|
||||
ssize_t n;
|
||||
|
||||
while (*iov_size > 0) {
|
||||
if (*iov_size == 1)
|
||||
n = read(fd->osfd, (*iov)->iov_base, (*iov)->iov_len);
|
||||
else
|
||||
n = readv(fd->osfd, *iov, *iov_size);
|
||||
if (n < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
if (!_IO_NOT_READY_ERROR)
|
||||
return -1;
|
||||
} else if (n == 0)
|
||||
break;
|
||||
else {
|
||||
while ((size_t) n >= (*iov)->iov_len) {
|
||||
n -= (*iov)->iov_len;
|
||||
(*iov)->iov_base = (char *) (*iov)->iov_base + (*iov)->iov_len;
|
||||
(*iov)->iov_len = 0;
|
||||
(*iov)++;
|
||||
(*iov_size)--;
|
||||
if (n == 0)
|
||||
break;
|
||||
}
|
||||
if (*iov_size == 0)
|
||||
break;
|
||||
(*iov)->iov_base = (char *) (*iov)->iov_base + n;
|
||||
(*iov)->iov_len -= n;
|
||||
}
|
||||
/* Wait until the socket becomes readable */
|
||||
if (st_netfd_poll(fd, POLLIN, timeout) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
ssize_t st_read_fully(_st_netfd_t *fd, void *buf, size_t nbyte, st_utime_t timeout)
|
||||
{
|
||||
size_t resid = nbyte;
|
||||
return st_read_resid(fd, buf, &resid, timeout) == 0 ?
|
||||
(ssize_t) (nbyte - resid) : -1;
|
||||
}
|
||||
|
||||
|
||||
int st_write_resid(_st_netfd_t *fd, const void *buf, size_t *resid, st_utime_t timeout)
|
||||
{
|
||||
struct iovec iov, *riov;
|
||||
int riov_size, rv;
|
||||
|
||||
iov.iov_base = (void *) buf; /* we promise not to modify buf */
|
||||
iov.iov_len = *resid;
|
||||
riov = &iov;
|
||||
riov_size = 1;
|
||||
rv = st_writev_resid(fd, &riov, &riov_size, timeout);
|
||||
*resid = iov.iov_len;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
ssize_t st_write(_st_netfd_t *fd, const void *buf, size_t nbyte, st_utime_t timeout)
|
||||
{
|
||||
size_t resid = nbyte;
|
||||
return st_write_resid(fd, buf, &resid, timeout) == 0 ?
|
||||
(ssize_t) (nbyte - resid) : -1;
|
||||
}
|
||||
|
||||
|
||||
ssize_t st_writev(_st_netfd_t *fd, const struct iovec *iov, int iov_size, st_utime_t timeout)
|
||||
{
|
||||
ssize_t n, rv;
|
||||
size_t nleft, nbyte;
|
||||
int index, iov_cnt;
|
||||
struct iovec *tmp_iov;
|
||||
struct iovec local_iov[_LOCAL_MAXIOV];
|
||||
|
||||
/* Calculate the total number of bytes to be sent */
|
||||
nbyte = 0;
|
||||
for (index = 0; index < iov_size; index++)
|
||||
nbyte += iov[index].iov_len;
|
||||
|
||||
rv = (ssize_t)nbyte;
|
||||
nleft = nbyte;
|
||||
tmp_iov = (struct iovec *) iov; /* we promise not to modify iov */
|
||||
iov_cnt = iov_size;
|
||||
|
||||
while (nleft > 0) {
|
||||
if (iov_cnt == 1) {
|
||||
if (st_write(fd, tmp_iov[0].iov_base, nleft, timeout) != (ssize_t) nleft)
|
||||
rv = -1;
|
||||
break;
|
||||
}
|
||||
if ((n = writev(fd->osfd, tmp_iov, iov_cnt)) < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
if (!_IO_NOT_READY_ERROR) {
|
||||
rv = -1;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if ((size_t) n == nleft)
|
||||
break;
|
||||
nleft -= n;
|
||||
/* Find the next unwritten vector */
|
||||
n = (ssize_t)(nbyte - nleft);
|
||||
for (index = 0; (size_t) n >= iov[index].iov_len; index++)
|
||||
n -= iov[index].iov_len;
|
||||
|
||||
if (tmp_iov == iov) {
|
||||
/* Must copy iov's around */
|
||||
if (iov_size - index <= _LOCAL_MAXIOV) {
|
||||
tmp_iov = local_iov;
|
||||
} else {
|
||||
tmp_iov = calloc(1, (iov_size - index) * sizeof(struct iovec));
|
||||
if (tmp_iov == NULL)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill in the first partial read */
|
||||
tmp_iov[0].iov_base = &(((char *)iov[index].iov_base)[n]);
|
||||
tmp_iov[0].iov_len = iov[index].iov_len - n;
|
||||
index++;
|
||||
/* Copy the remaining vectors */
|
||||
for (iov_cnt = 1; index < iov_size; iov_cnt++, index++) {
|
||||
tmp_iov[iov_cnt].iov_base = iov[index].iov_base;
|
||||
tmp_iov[iov_cnt].iov_len = iov[index].iov_len;
|
||||
}
|
||||
}
|
||||
/* Wait until the socket becomes writable */
|
||||
if (st_netfd_poll(fd, POLLOUT, timeout) < 0) {
|
||||
rv = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (tmp_iov != iov && tmp_iov != local_iov)
|
||||
free(tmp_iov);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
int st_writev_resid(_st_netfd_t *fd, struct iovec **iov, int *iov_size, st_utime_t timeout)
|
||||
{
|
||||
ssize_t n;
|
||||
|
||||
while (*iov_size > 0) {
|
||||
if (*iov_size == 1)
|
||||
n = write(fd->osfd, (*iov)->iov_base, (*iov)->iov_len);
|
||||
else
|
||||
n = writev(fd->osfd, *iov, *iov_size);
|
||||
if (n < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
if (!_IO_NOT_READY_ERROR)
|
||||
return -1;
|
||||
} else {
|
||||
while ((size_t) n >= (*iov)->iov_len) {
|
||||
n -= (*iov)->iov_len;
|
||||
(*iov)->iov_base = (char *) (*iov)->iov_base + (*iov)->iov_len;
|
||||
(*iov)->iov_len = 0;
|
||||
(*iov)++;
|
||||
(*iov_size)--;
|
||||
if (n == 0)
|
||||
break;
|
||||
}
|
||||
if (*iov_size == 0)
|
||||
break;
|
||||
(*iov)->iov_base = (char *) (*iov)->iov_base + n;
|
||||
(*iov)->iov_len -= n;
|
||||
}
|
||||
/* Wait until the socket becomes writable */
|
||||
if (st_netfd_poll(fd, POLLOUT, timeout) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Simple I/O functions for UDP.
|
||||
*/
|
||||
int st_recvfrom(_st_netfd_t *fd, void *buf, int len, struct sockaddr *from, int *fromlen, st_utime_t timeout)
|
||||
{
|
||||
int n;
|
||||
|
||||
while ((n = recvfrom(fd->osfd, buf, len, 0, from, (socklen_t *)fromlen)) < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
if (!_IO_NOT_READY_ERROR)
|
||||
return -1;
|
||||
/* Wait until the socket becomes readable */
|
||||
if (st_netfd_poll(fd, POLLIN, timeout) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
int st_sendto(_st_netfd_t *fd, const void *msg, int len, const struct sockaddr *to, int tolen, st_utime_t timeout)
|
||||
{
|
||||
int n;
|
||||
|
||||
while ((n = sendto(fd->osfd, msg, len, 0, to, tolen)) < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
if (!_IO_NOT_READY_ERROR)
|
||||
return -1;
|
||||
/* Wait until the socket becomes writable */
|
||||
if (st_netfd_poll(fd, POLLOUT, timeout) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
int st_recvmsg(_st_netfd_t *fd, struct msghdr *msg, int flags, st_utime_t timeout)
|
||||
{
|
||||
int n;
|
||||
|
||||
while ((n = recvmsg(fd->osfd, msg, flags)) < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
if (!_IO_NOT_READY_ERROR)
|
||||
return -1;
|
||||
/* Wait until the socket becomes readable */
|
||||
if (st_netfd_poll(fd, POLLIN, timeout) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
int st_sendmsg(_st_netfd_t *fd, const struct msghdr *msg, int flags, st_utime_t timeout)
|
||||
{
|
||||
int n;
|
||||
|
||||
while ((n = sendmsg(fd->osfd, msg, flags)) < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
if (!_IO_NOT_READY_ERROR)
|
||||
return -1;
|
||||
/* Wait until the socket becomes writable */
|
||||
if (st_netfd_poll(fd, POLLOUT, timeout) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* To open FIFOs or other special files.
|
||||
*/
|
||||
_st_netfd_t *st_open(const char *path, int oflags, mode_t mode)
|
||||
{
|
||||
int osfd, err;
|
||||
_st_netfd_t *newfd;
|
||||
|
||||
while ((osfd = open(path, oflags | O_NONBLOCK, mode)) < 0) {
|
||||
if (errno != EINTR)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
newfd = _st_netfd_new(osfd, 0, 0);
|
||||
if (!newfd) {
|
||||
err = errno;
|
||||
close(osfd);
|
||||
errno = err;
|
||||
}
|
||||
|
||||
return newfd;
|
||||
}
|
||||
|
121
trunk/3rdparty/st-srs/key.c
vendored
Normal file
121
trunk/3rdparty/st-srs/key.c
vendored
Normal file
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape Portable Runtime library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Silicon Graphics, Inc.
|
||||
*
|
||||
* Portions created by SGI are Copyright (C) 2000-2001 Silicon
|
||||
* Graphics, Inc. All Rights Reserved.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is derived directly from Netscape Communications Corporation,
|
||||
* and consists of extensive modifications made during the year(s) 1999-2000.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include "common.h"
|
||||
|
||||
|
||||
/*
|
||||
* Destructor table for per-thread private data
|
||||
*/
|
||||
static _st_destructor_t _st_destructors[ST_KEYS_MAX];
|
||||
static int key_max = 0;
|
||||
|
||||
|
||||
/*
|
||||
* Return a key to be used for thread specific data
|
||||
*/
|
||||
int st_key_create(int *keyp, _st_destructor_t destructor)
|
||||
{
|
||||
if (key_max >= ST_KEYS_MAX) {
|
||||
errno = EAGAIN;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*keyp = key_max++;
|
||||
_st_destructors[*keyp] = destructor;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int st_key_getlimit(void)
|
||||
{
|
||||
return ST_KEYS_MAX;
|
||||
}
|
||||
|
||||
|
||||
int st_thread_setspecific(int key, void *value)
|
||||
{
|
||||
_st_thread_t *me = _ST_CURRENT_THREAD();
|
||||
|
||||
if (key < 0 || key >= key_max) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (value != me->private_data[key]) {
|
||||
/* free up previously set non-NULL data value */
|
||||
if (me->private_data[key] && _st_destructors[key]) {
|
||||
(*_st_destructors[key])(me->private_data[key]);
|
||||
}
|
||||
me->private_data[key] = value;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void *st_thread_getspecific(int key)
|
||||
{
|
||||
if (key < 0 || key >= key_max)
|
||||
return NULL;
|
||||
|
||||
return ((_ST_CURRENT_THREAD())->private_data[key]);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Free up all per-thread private data
|
||||
*/
|
||||
void _st_thread_cleanup(_st_thread_t *thread)
|
||||
{
|
||||
int key;
|
||||
|
||||
for (key = 0; key < key_max; key++) {
|
||||
if (thread->private_data[key] && _st_destructors[key]) {
|
||||
(*_st_destructors[key])(thread->private_data[key]);
|
||||
thread->private_data[key] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
51
trunk/3rdparty/st-srs/libst.def
vendored
Normal file
51
trunk/3rdparty/st-srs/libst.def
vendored
Normal file
|
@ -0,0 +1,51 @@
|
|||
EXPORTS
|
||||
st_accept @62
|
||||
st_cond_broadcast @63
|
||||
st_cond_destroy @64
|
||||
st_cond_new @65
|
||||
st_cond_signal @66
|
||||
st_cond_timedwait @67
|
||||
st_cond_wait @68
|
||||
st_connect @69
|
||||
st_getfdlimit @70
|
||||
st_init @71
|
||||
st_key_create @72
|
||||
st_key_getlimit @73
|
||||
st_mutex_destroy @74
|
||||
st_mutex_lock @75
|
||||
st_mutex_new @76
|
||||
st_mutex_trylock @77
|
||||
st_mutex_unlock @78
|
||||
st_netfd_close @79
|
||||
st_netfd_fileno @80
|
||||
st_netfd_free @81
|
||||
st_netfd_getspecific @82
|
||||
st_netfd_open @83
|
||||
st_netfd_open_socket @84
|
||||
st_netfd_poll @85
|
||||
st_netfd_serialize_accept @86
|
||||
st_netfd_setspecific @87
|
||||
st_open @88
|
||||
st_poll @89
|
||||
st_randomize_stacks @90
|
||||
st_read @91
|
||||
st_read_fully @92
|
||||
st_read_resid @93
|
||||
st_recvfrom @94
|
||||
st_sendto @95
|
||||
st_sleep @96
|
||||
st_thread_create @97
|
||||
st_thread_exit @98
|
||||
st_thread_getspecific @99
|
||||
st_thread_interrupt @100
|
||||
st_thread_join @101
|
||||
st_thread_self @102
|
||||
st_thread_setspecific @103
|
||||
st_time @104
|
||||
st_timecache_set @105
|
||||
st_usleep @106
|
||||
st_utime @107
|
||||
st_utime_last_clock @108
|
||||
st_write @109
|
||||
st_write_resid @110
|
||||
st_writev @111
|
644
trunk/3rdparty/st-srs/md.S
vendored
Normal file
644
trunk/3rdparty/st-srs/md.S
vendored
Normal file
|
@ -0,0 +1,644 @@
|
|||
|
||||
/* If user disable the ASM, such as avoiding bugs in ASM, donot compile it. */
|
||||
#if !defined(MD_ST_NO_ASM)
|
||||
|
||||
/*
|
||||
* Portions created by SGI are Copyright (C) 2000 Silicon Graphics, Inc.
|
||||
* All Rights Reserved.
|
||||
*/
|
||||
|
||||
#if defined(__ia64__)
|
||||
|
||||
/****************************************************************/
|
||||
|
||||
/*
|
||||
* The internal __jmp_buf layout is different from one used
|
||||
* by setjmp()/longjmp().
|
||||
*
|
||||
* Offset Description
|
||||
* ------ -----------
|
||||
* 0x000 stack pointer (r12)
|
||||
* 0x008 gp (r1)
|
||||
* 0x010 caller's unat
|
||||
* 0x018 fpsr
|
||||
* 0x020 r4
|
||||
* 0x028 r5
|
||||
* 0x030 r6
|
||||
* 0x038 r7
|
||||
* 0x040 rp (b0)
|
||||
* 0x048 b1
|
||||
* 0x050 b2
|
||||
* 0x058 b3
|
||||
* 0x060 b4
|
||||
* 0x068 b5
|
||||
* 0x070 ar.pfs
|
||||
* 0x078 ar.lc
|
||||
* 0x080 pr
|
||||
* 0x088 ar.bsp
|
||||
* 0x090 ar.unat
|
||||
* 0x098 &__jmp_buf
|
||||
* 0x0a0 ar.rsc
|
||||
* 0x0a8 ar.rnat
|
||||
* 0x0b0 f2
|
||||
* 0x0c0 f3
|
||||
* 0x0d0 f4
|
||||
* 0x0e0 f5
|
||||
* 0x0f0 f16
|
||||
* 0x100 f17
|
||||
* 0x110 f18
|
||||
* 0x120 f19
|
||||
* 0x130 f20
|
||||
* 0x130 f21
|
||||
* 0x140 f22
|
||||
* 0x150 f23
|
||||
* 0x160 f24
|
||||
* 0x170 f25
|
||||
* 0x180 f26
|
||||
* 0x190 f27
|
||||
* 0x1a0 f28
|
||||
* 0x1b0 f29
|
||||
* 0x1c0 f30
|
||||
* 0x1d0 f31
|
||||
*
|
||||
* Note that the address of __jmp_buf is saved but not used: we assume
|
||||
* that the jmp_buf data structure is never moved around in memory.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Implemented according to "IA-64 Software Conventions and Runtime
|
||||
* Architecture Guide", Chapter 10: "Context Management".
|
||||
*/
|
||||
|
||||
.text
|
||||
.psr abi64
|
||||
.psr lsb
|
||||
.lsb
|
||||
|
||||
/* _st_md_cxt_save(__jmp_buf env) */
|
||||
.align 32
|
||||
.global _st_md_cxt_save
|
||||
.proc _st_md_cxt_save
|
||||
_st_md_cxt_save:
|
||||
alloc r14 = ar.pfs,1,0,0,0
|
||||
mov r16 = ar.unat
|
||||
;;
|
||||
mov r17 = ar.fpsr
|
||||
mov r2 = in0
|
||||
add r3 = 8,in0
|
||||
;;
|
||||
st8.spill.nta [r2] = sp,16 // r12 (sp)
|
||||
;;
|
||||
st8.spill.nta [r3] = gp,16 // r1 (gp)
|
||||
;;
|
||||
st8.nta [r2] = r16,16 // save caller's unat
|
||||
st8.nta [r3] = r17,16 // save fpsr
|
||||
add r8 = 0xb0,in0
|
||||
;;
|
||||
st8.spill.nta [r2] = r4,16 // r4
|
||||
;;
|
||||
st8.spill.nta [r3] = r5,16 // r5
|
||||
add r9 = 0xc0,in0
|
||||
;;
|
||||
stf.spill.nta [r8] = f2,32
|
||||
stf.spill.nta [r9] = f3,32
|
||||
mov r15 = rp
|
||||
;;
|
||||
stf.spill.nta [r8] = f4,32
|
||||
stf.spill.nta [r9] = f5,32
|
||||
mov r17 = b1
|
||||
;;
|
||||
stf.spill.nta [r8] = f16,32
|
||||
stf.spill.nta [r9] = f17,32
|
||||
mov r18 = b2
|
||||
;;
|
||||
stf.spill.nta [r8] = f18,32
|
||||
stf.spill.nta [r9] = f19,32
|
||||
mov r19 = b3
|
||||
;;
|
||||
stf.spill.nta [r8] = f20,32
|
||||
stf.spill.nta [r9] = f21,32
|
||||
mov r20 = b4
|
||||
;;
|
||||
stf.spill.nta [r8] = f22,32
|
||||
stf.spill.nta [r9] = f23,32
|
||||
mov r21 = b5
|
||||
;;
|
||||
stf.spill.nta [r8] = f24,32
|
||||
stf.spill.nta [r9] = f25,32
|
||||
mov r22 = ar.lc
|
||||
;;
|
||||
stf.spill.nta [r8] = f26,32
|
||||
stf.spill.nta [r9] = f27,32
|
||||
mov r24 = pr
|
||||
;;
|
||||
stf.spill.nta [r8] = f28,32
|
||||
stf.spill.nta [r9] = f29,32
|
||||
;;
|
||||
stf.spill.nta [r8] = f30
|
||||
stf.spill.nta [r9] = f31
|
||||
|
||||
st8.spill.nta [r2] = r6,16 // r6
|
||||
;;
|
||||
st8.spill.nta [r3] = r7,16 // r7
|
||||
;;
|
||||
mov r23 = ar.bsp
|
||||
mov r25 = ar.unat
|
||||
|
||||
st8.nta [r2] = r15,16 // b0
|
||||
st8.nta [r3] = r17,16 // b1
|
||||
;;
|
||||
st8.nta [r2] = r18,16 // b2
|
||||
st8.nta [r3] = r19,16 // b3
|
||||
mov r26 = ar.rsc
|
||||
;;
|
||||
st8.nta [r2] = r20,16 // b4
|
||||
st8.nta [r3] = r21,16 // b5
|
||||
;;
|
||||
st8.nta [r2] = r14,16 // ar.pfs
|
||||
st8.nta [r3] = r22,16 // ar.lc
|
||||
;;
|
||||
st8.nta [r2] = r24,16 // pr
|
||||
st8.nta [r3] = r23,16 // ar.bsp
|
||||
;;
|
||||
st8.nta [r2] = r25,16 // ar.unat
|
||||
st8.nta [r3] = in0,16 // &__jmp_buf (just in case)
|
||||
;;
|
||||
st8.nta [r2] = r26 // ar.rsc
|
||||
;;
|
||||
flushrs // flush dirty regs to backing store
|
||||
;;
|
||||
and r27 = ~0x3,r26 // clear ar.rsc.mode
|
||||
;;
|
||||
mov ar.rsc = r27 // put RSE in enforced lazy mode
|
||||
;;
|
||||
mov r28 = ar.rnat
|
||||
;;
|
||||
st8.nta [r3] = r28 // ar.rnat
|
||||
mov ar.rsc = r26 // restore ar.rsc
|
||||
;;
|
||||
mov r8 = 0
|
||||
br.ret.sptk.few b0
|
||||
.endp _st_md_cxt_save
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
|
||||
/* _st_md_cxt_restore(__jmp_buf env, int val) */
|
||||
.global _st_md_cxt_restore
|
||||
.proc _st_md_cxt_restore
|
||||
_st_md_cxt_restore:
|
||||
alloc r8 = ar.pfs,2,0,0,0
|
||||
add r2 = 0x88,in0 // r2 <- &jmpbuf.ar_bsp
|
||||
mov r16 = ar.rsc
|
||||
;;
|
||||
flushrs // flush dirty regs to backing store
|
||||
;;
|
||||
and r17 = ~0x3,r16 // clear ar.rsc.mode
|
||||
;;
|
||||
mov ar.rsc = r17 // put RSE in enforced lazy mode
|
||||
;;
|
||||
invala // invalidate the ALAT
|
||||
;;
|
||||
ld8 r23 = [r2],8 // r23 <- jmpbuf.ar_bsp
|
||||
;;
|
||||
mov ar.bspstore = r23 // write BSPSTORE
|
||||
ld8 r25 = [r2],24 // r25 <- jmpbuf.ar_unat
|
||||
;;
|
||||
ld8 r26 = [r2],-8 // r26 <- jmpbuf.ar_rnat
|
||||
;;
|
||||
mov ar.rnat = r26 // write RNAT
|
||||
ld8 r27 = [r2] // r27 <- jmpbuf.ar_rsc
|
||||
;;
|
||||
mov ar.rsc = r27 // write RSE control
|
||||
mov r2 = in0
|
||||
;;
|
||||
mov ar.unat = r25 // write ar.unat
|
||||
add r3 = 8,in0
|
||||
;;
|
||||
ld8.fill.nta sp = [r2],16 // r12 (sp)
|
||||
ld8.fill.nta gp = [r3],16 // r1 (gp)
|
||||
;;
|
||||
ld8.nta r16 = [r2],16 // caller's unat
|
||||
ld8.nta r17 = [r3],16 // fpsr
|
||||
;;
|
||||
ld8.fill.nta r4 = [r2],16 // r4
|
||||
ld8.fill.nta r5 = [r3],16 // r5
|
||||
;;
|
||||
ld8.fill.nta r6 = [r2],16 // r6
|
||||
ld8.fill.nta r7 = [r3],16 // r7
|
||||
;;
|
||||
mov ar.unat = r16 // restore caller's unat
|
||||
mov ar.fpsr = r17 // restore fpsr
|
||||
;;
|
||||
ld8.nta r16 = [r2],16 // b0
|
||||
ld8.nta r17 = [r3],16 // b1
|
||||
;;
|
||||
ld8.nta r18 = [r2],16 // b2
|
||||
ld8.nta r19 = [r3],16 // b3
|
||||
;;
|
||||
ld8.nta r20 = [r2],16 // b4
|
||||
ld8.nta r21 = [r3],16 // b5
|
||||
;;
|
||||
ld8.nta r11 = [r2],16 // ar.pfs
|
||||
ld8.nta r22 = [r3],72 // ar.lc
|
||||
;;
|
||||
ld8.nta r24 = [r2],48 // pr
|
||||
mov b0 = r16
|
||||
;;
|
||||
ldf.fill.nta f2 = [r2],32
|
||||
ldf.fill.nta f3 = [r3],32
|
||||
mov b1 = r17
|
||||
;;
|
||||
ldf.fill.nta f4 = [r2],32
|
||||
ldf.fill.nta f5 = [r3],32
|
||||
mov b2 = r18
|
||||
;;
|
||||
ldf.fill.nta f16 = [r2],32
|
||||
ldf.fill.nta f17 = [r3],32
|
||||
mov b3 = r19
|
||||
;;
|
||||
ldf.fill.nta f18 = [r2],32
|
||||
ldf.fill.nta f19 = [r3],32
|
||||
mov b4 = r20
|
||||
;;
|
||||
ldf.fill.nta f20 = [r2],32
|
||||
ldf.fill.nta f21 = [r3],32
|
||||
mov b5 = r21
|
||||
;;
|
||||
ldf.fill.nta f22 = [r2],32
|
||||
ldf.fill.nta f23 = [r3],32
|
||||
mov ar.lc = r22
|
||||
;;
|
||||
ldf.fill.nta f24 = [r2],32
|
||||
ldf.fill.nta f25 = [r3],32
|
||||
cmp.eq p6,p7 = 0,in1
|
||||
;;
|
||||
ldf.fill.nta f26 = [r2],32
|
||||
ldf.fill.nta f27 = [r3],32
|
||||
mov ar.pfs = r11
|
||||
;;
|
||||
ldf.fill.nta f28 = [r2],32
|
||||
ldf.fill.nta f29 = [r3],32
|
||||
;;
|
||||
ldf.fill.nta f30 = [r2]
|
||||
ldf.fill.nta f31 = [r3]
|
||||
(p6) mov r8 = 1
|
||||
(p7) mov r8 = in1
|
||||
|
||||
mov pr = r24,-1
|
||||
br.ret.sptk.few b0
|
||||
.endp _st_md_cxt_restore
|
||||
|
||||
/****************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#elif defined(__i386__)
|
||||
|
||||
/****************************************************************/
|
||||
|
||||
/*
|
||||
* Internal __jmp_buf layout
|
||||
*/
|
||||
#define JB_BX 0
|
||||
#define JB_SI 1
|
||||
#define JB_DI 2
|
||||
#define JB_BP 3
|
||||
#define JB_SP 4
|
||||
#define JB_PC 5
|
||||
|
||||
.file "md.S"
|
||||
.text
|
||||
|
||||
/* _st_md_cxt_save(__jmp_buf env) */
|
||||
.globl _st_md_cxt_save
|
||||
.type _st_md_cxt_save, @function
|
||||
.align 16
|
||||
_st_md_cxt_save:
|
||||
movl 4(%esp), %eax
|
||||
|
||||
/*
|
||||
* Save registers.
|
||||
*/
|
||||
movl %ebx, (JB_BX*4)(%eax)
|
||||
movl %esi, (JB_SI*4)(%eax)
|
||||
movl %edi, (JB_DI*4)(%eax)
|
||||
/* Save SP */
|
||||
leal 4(%esp), %ecx
|
||||
movl %ecx, (JB_SP*4)(%eax)
|
||||
/* Save PC we are returning to */
|
||||
movl 0(%esp), %ecx
|
||||
movl %ecx, (JB_PC*4)(%eax)
|
||||
/* Save caller frame pointer */
|
||||
movl %ebp, (JB_BP*4)(%eax)
|
||||
xorl %eax, %eax
|
||||
ret
|
||||
.size _st_md_cxt_save, .-_st_md_cxt_save
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
|
||||
/* _st_md_cxt_restore(__jmp_buf env, int val) */
|
||||
.globl _st_md_cxt_restore
|
||||
.type _st_md_cxt_restore, @function
|
||||
.align 16
|
||||
_st_md_cxt_restore:
|
||||
/* First argument is jmp_buf */
|
||||
movl 4(%esp), %ecx
|
||||
/* Second argument is return value */
|
||||
movl 8(%esp), %eax
|
||||
/* Set the return address */
|
||||
movl (JB_PC*4)(%ecx), %edx
|
||||
/*
|
||||
* Restore registers.
|
||||
*/
|
||||
movl (JB_BX*4)(%ecx), %ebx
|
||||
movl (JB_SI*4)(%ecx), %esi
|
||||
movl (JB_DI*4)(%ecx), %edi
|
||||
movl (JB_BP*4)(%ecx), %ebp
|
||||
movl (JB_SP*4)(%ecx), %esp
|
||||
testl %eax, %eax
|
||||
jnz 1f
|
||||
incl %eax
|
||||
/* Jump to saved PC */
|
||||
1: jmp *%edx
|
||||
.size _st_md_cxt_restore, .-_st_md_cxt_restore
|
||||
|
||||
/****************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#elif defined(__amd64__) || defined(__x86_64__)
|
||||
|
||||
/****************************************************************/
|
||||
|
||||
/*
|
||||
* Internal __jmp_buf layout
|
||||
*/
|
||||
#define JB_RBX 0
|
||||
#define JB_RBP 1
|
||||
#define JB_R12 2
|
||||
#define JB_R13 3
|
||||
#define JB_R14 4
|
||||
#define JB_R15 5
|
||||
#define JB_RSP 6
|
||||
#define JB_PC 7
|
||||
|
||||
.file "md.S"
|
||||
.text
|
||||
|
||||
/* _st_md_cxt_save(__jmp_buf env) */
|
||||
.globl _st_md_cxt_save
|
||||
.type _st_md_cxt_save, @function
|
||||
.align 16
|
||||
_st_md_cxt_save:
|
||||
/*
|
||||
* Save registers.
|
||||
*/
|
||||
movq %rbx, (JB_RBX*8)(%rdi)
|
||||
movq %rbp, (JB_RBP*8)(%rdi)
|
||||
movq %r12, (JB_R12*8)(%rdi)
|
||||
movq %r13, (JB_R13*8)(%rdi)
|
||||
movq %r14, (JB_R14*8)(%rdi)
|
||||
movq %r15, (JB_R15*8)(%rdi)
|
||||
/* Save SP */
|
||||
leaq 8(%rsp), %rdx
|
||||
movq %rdx, (JB_RSP*8)(%rdi)
|
||||
/* Save PC we are returning to */
|
||||
movq (%rsp), %rax
|
||||
movq %rax, (JB_PC*8)(%rdi)
|
||||
xorq %rax, %rax
|
||||
ret
|
||||
.size _st_md_cxt_save, .-_st_md_cxt_save
|
||||
|
||||
|
||||
/****************************************************************/
|
||||
|
||||
/* _st_md_cxt_restore(__jmp_buf env, int val) */
|
||||
.globl _st_md_cxt_restore
|
||||
.type _st_md_cxt_restore, @function
|
||||
.align 16
|
||||
_st_md_cxt_restore:
|
||||
/*
|
||||
* Restore registers.
|
||||
*/
|
||||
movq (JB_RBX*8)(%rdi), %rbx
|
||||
movq (JB_RBP*8)(%rdi), %rbp
|
||||
movq (JB_R12*8)(%rdi), %r12
|
||||
movq (JB_R13*8)(%rdi), %r13
|
||||
movq (JB_R14*8)(%rdi), %r14
|
||||
movq (JB_R15*8)(%rdi), %r15
|
||||
/* Set return value */
|
||||
test %esi, %esi
|
||||
mov $01, %eax
|
||||
cmove %eax, %esi
|
||||
mov %esi, %eax
|
||||
movq (JB_PC*8)(%rdi), %rdx
|
||||
movq (JB_RSP*8)(%rdi), %rsp
|
||||
/* Jump to saved PC */
|
||||
jmpq *%rdx
|
||||
.size _st_md_cxt_restore, .-_st_md_cxt_restore
|
||||
|
||||
/****************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#elif defined(__aarch64__)
|
||||
|
||||
/****************************************************************/
|
||||
/* https://github.com/ossrs/srs/issues/1282#issuecomment-445539513 */
|
||||
|
||||
#define JB_X19 0
|
||||
#define JB_X20 1
|
||||
#define JB_X21 2
|
||||
#define JB_X22 3
|
||||
#define JB_X23 4
|
||||
#define JB_X24 5
|
||||
#define JB_X25 6
|
||||
#define JB_X26 7
|
||||
#define JB_X27 8
|
||||
#define JB_X28 9
|
||||
#define JB_X29 10
|
||||
#define JB_LR 11
|
||||
#define JB_SP 13
|
||||
|
||||
#define JB_D8 14
|
||||
#define JB_D9 15
|
||||
#define JB_D10 16
|
||||
#define JB_D11 17
|
||||
#define JB_D12 18
|
||||
#define JB_D13 19
|
||||
#define JB_D14 20
|
||||
#define JB_D15 21
|
||||
|
||||
.file "md.S"
|
||||
.text
|
||||
|
||||
/* _st_md_cxt_save(__jmp_buf env) */
|
||||
.globl _st_md_cxt_save
|
||||
.type _st_md_cxt_save, %function
|
||||
.align 4
|
||||
_st_md_cxt_save:
|
||||
stp x19, x20, [x0, #JB_X19<<3]
|
||||
stp x21, x22, [x0, #JB_X21<<3]
|
||||
stp x23, x24, [x0, #JB_X23<<3]
|
||||
stp x25, x26, [x0, #JB_X25<<3]
|
||||
stp x27, x28, [x0, #JB_X27<<3]
|
||||
stp x29, x30, [x0, #JB_X29<<3]
|
||||
|
||||
stp d8, d9, [x0, #JB_D8<<3]
|
||||
stp d10, d11, [x0, #JB_D10<<3]
|
||||
stp d12, d13, [x0, #JB_D12<<3]
|
||||
stp d14, d15, [x0, #JB_D14<<3]
|
||||
mov x2, sp
|
||||
str x2, [x0, #JB_SP<<3]
|
||||
|
||||
mov x0, #0
|
||||
ret
|
||||
.size _st_md_cxt_save, .-_st_md_cxt_save
|
||||
|
||||
/****************************************************************/
|
||||
|
||||
/* _st_md_cxt_restore(__jmp_buf env, int val) */
|
||||
.globl _st_md_cxt_restore
|
||||
.type _st_md_cxt_restore, %function
|
||||
.align 4
|
||||
_st_md_cxt_restore:
|
||||
ldp x19, x20, [x0, #JB_X19<<3]
|
||||
ldp x21, x22, [x0, #JB_X21<<3]
|
||||
ldp x23, x24, [x0, #JB_X23<<3]
|
||||
ldp x25, x26, [x0, #JB_X25<<3]
|
||||
ldp x27, x28, [x0, #JB_X27<<3]
|
||||
|
||||
ldp x29, x30, [x0, #JB_X29<<3]
|
||||
|
||||
ldp d8, d9, [x0, #JB_D8<<3]
|
||||
ldp d10, d11, [x0, #JB_D10<<3]
|
||||
ldp d12, d13, [x0, #JB_D12<<3]
|
||||
ldp d14, d15, [x0, #JB_D14<<3]
|
||||
|
||||
ldr x5, [x0, #JB_SP<<3]
|
||||
mov sp, x5
|
||||
|
||||
cmp x1, #0
|
||||
mov x0, #1
|
||||
csel x0, x1, x0, ne
|
||||
/* Use br instead of ret because ret is guaranteed to mispredict */
|
||||
br x30
|
||||
.size _st_md_cxt_restore, .-_st_md_cxt_restore
|
||||
|
||||
/****************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#elif defined(__arm__)
|
||||
|
||||
/****************************************************************/
|
||||
/* https://github.com/ossrs/srs/issues/1282#issuecomment-445539513 */
|
||||
|
||||
/* Register list for a ldm/stm instruction to load/store
|
||||
the general registers from a __jmp_buf. */
|
||||
# define JMP_BUF_REGLIST {v1-v6, sl, fp, sp, lr}
|
||||
|
||||
.file "md.S"
|
||||
.text
|
||||
|
||||
/* _st_md_cxt_save(__jmp_buf env) */
|
||||
.globl _st_md_cxt_save
|
||||
.type _st_md_cxt_save, %function
|
||||
.align 2
|
||||
_st_md_cxt_save:
|
||||
mov ip, r0
|
||||
|
||||
/* Save registers */
|
||||
stmia ip!, JMP_BUF_REGLIST
|
||||
|
||||
#ifdef __VFP_FP__
|
||||
/* Store the VFP registers. */
|
||||
/* Following instruction is vstmia ip!, {d8-d15}. */
|
||||
stc p11, cr8, [ip], #64
|
||||
#endif
|
||||
|
||||
#ifdef __IWMMXT__
|
||||
/* Save the call-preserved iWMMXt registers. */
|
||||
/* Following instructions are wstrd wr10, [ip], #8 (etc.) */
|
||||
stcl p1, cr10, [r12], #8
|
||||
stcl p1, cr11, [r12], #8
|
||||
stcl p1, cr12, [r12], #8
|
||||
stcl p1, cr13, [r12], #8
|
||||
stcl p1, cr14, [r12], #8
|
||||
stcl p1, cr15, [r12], #8
|
||||
#endif
|
||||
|
||||
mov r0, #0
|
||||
bx lr
|
||||
|
||||
.size _st_md_cxt_save, .-_st_md_cxt_save
|
||||
|
||||
/****************************************************************/
|
||||
|
||||
/* _st_md_cxt_restore(__jmp_buf env, int val) */
|
||||
.globl _st_md_cxt_restore
|
||||
.type _st_md_cxt_restore, %function
|
||||
.align 2
|
||||
_st_md_cxt_restore:
|
||||
mov ip, r0
|
||||
|
||||
/* Restore registers */
|
||||
ldmia ip!, JMP_BUF_REGLIST
|
||||
|
||||
#ifdef __VFP_FP__
|
||||
/* Restore the VFP registers. */
|
||||
/* Following instruction is vldmia ip!, {d8-d15}. */
|
||||
ldc p11, cr8, [r12], #64
|
||||
#endif
|
||||
|
||||
#ifdef __IWMMXT__
|
||||
/* Restore the call-preserved iWMMXt registers. */
|
||||
/* Following instructions are wldrd wr10, [ip], #8 (etc.) */
|
||||
ldcl p1, cr10, [r12], #8
|
||||
ldcl p1, cr11, [r12], #8
|
||||
ldcl p1, cr12, [r12], #8
|
||||
ldcl p1, cr13, [r12], #8
|
||||
ldcl p1, cr14, [r12], #8
|
||||
ldcl p1, cr15, [r12], #8
|
||||
#endif
|
||||
|
||||
movs r0, r1 /* get the return value in place */
|
||||
moveq r0, #1 /* can't let setjmp() return zero! */
|
||||
bx lr
|
||||
|
||||
.size _st_md_cxt_restore, .-_st_md_cxt_restore
|
||||
|
||||
/****************************************************************/
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
641
trunk/3rdparty/st-srs/md.h
vendored
Normal file
641
trunk/3rdparty/st-srs/md.h
vendored
Normal file
|
@ -0,0 +1,641 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape Portable Runtime library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Silicon Graphics, Inc.
|
||||
*
|
||||
* Portions created by SGI are Copyright (C) 2000-2001 Silicon
|
||||
* Graphics, Inc. All Rights Reserved.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is derived directly from Netscape Communications Corporation,
|
||||
* and consists of extensive modifications made during the year(s) 1999-2000.
|
||||
*/
|
||||
|
||||
#ifndef __ST_MD_H__
|
||||
#define __ST_MD_H__
|
||||
|
||||
#if defined(ETIMEDOUT) && !defined(ETIME)
|
||||
#define ETIME ETIMEDOUT
|
||||
#endif
|
||||
|
||||
#if defined(MAP_ANONYMOUS) && !defined(MAP_ANON)
|
||||
#define MAP_ANON MAP_ANONYMOUS
|
||||
#endif
|
||||
|
||||
#ifndef MAP_FAILED
|
||||
#define MAP_FAILED -1
|
||||
#endif
|
||||
|
||||
/*****************************************
|
||||
* Platform specifics
|
||||
*/
|
||||
|
||||
#if defined (AIX)
|
||||
|
||||
#define MD_STACK_GROWS_DOWN
|
||||
#define MD_USE_SYSV_ANON_MMAP
|
||||
#define MD_ACCEPT_NB_INHERITED
|
||||
#define MD_ALWAYS_UNSERIALIZED_ACCEPT
|
||||
|
||||
#ifndef MD_HAVE_SOCKLEN_T
|
||||
#define MD_HAVE_SOCKLEN_T
|
||||
#define socklen_t unsigned long
|
||||
#endif
|
||||
|
||||
#define MD_SETJMP(env) _setjmp(env)
|
||||
#define MD_LONGJMP(env, val) _longjmp(env, val)
|
||||
|
||||
#define MD_INIT_CONTEXT(_thread, _sp, _main) \
|
||||
ST_BEGIN_MACRO \
|
||||
if (MD_SETJMP((_thread)->context)) \
|
||||
_main(); \
|
||||
(_thread)->context[3] = (long) (_sp); \
|
||||
ST_END_MACRO
|
||||
|
||||
#define MD_GET_UTIME() \
|
||||
timebasestruct_t rt; \
|
||||
(void) read_real_time(&rt, TIMEBASE_SZ); \
|
||||
(void) time_base_to_time(&rt, TIMEBASE_SZ); \
|
||||
return (rt.tb_high * 1000000LL + rt.tb_low / 1000)
|
||||
|
||||
#elif defined (CYGWIN)
|
||||
|
||||
#define MD_STACK_GROWS_DOWN
|
||||
#define MD_USE_BSD_ANON_MMAP
|
||||
#define MD_ACCEPT_NB_NOT_INHERITED
|
||||
#define MD_ALWAYS_UNSERIALIZED_ACCEPT
|
||||
|
||||
#define MD_SETJMP(env) setjmp(env)
|
||||
#define MD_LONGJMP(env, val) longjmp(env, val)
|
||||
|
||||
#define MD_JB_SP 7
|
||||
|
||||
#define MD_GET_SP(_t) (_t)->context[MD_JB_SP]
|
||||
|
||||
#define MD_INIT_CONTEXT(_thread, _sp, _main) \
|
||||
ST_BEGIN_MACRO \
|
||||
if (MD_SETJMP((_thread)->context)) \
|
||||
_main(); \
|
||||
MD_GET_SP(_thread) = (long) (_sp); \
|
||||
ST_END_MACRO
|
||||
|
||||
#define MD_GET_UTIME() \
|
||||
struct timeval tv; \
|
||||
(void) gettimeofday(&tv, NULL); \
|
||||
return (tv.tv_sec * 1000000LL + tv.tv_usec)
|
||||
|
||||
#elif defined (DARWIN)
|
||||
|
||||
#define MD_STACK_GROWS_DOWN
|
||||
#define MD_USE_BSD_ANON_MMAP
|
||||
#define MD_ACCEPT_NB_INHERITED
|
||||
#define MD_ALWAYS_UNSERIALIZED_ACCEPT
|
||||
#define MD_HAVE_SOCKLEN_T
|
||||
|
||||
#define MD_SETJMP(env) _setjmp(env)
|
||||
#define MD_LONGJMP(env, val) _longjmp(env, val)
|
||||
|
||||
#if defined(__ppc__)
|
||||
#define MD_JB_SP 0
|
||||
#elif defined(__i386__)
|
||||
#define MD_JB_SP 9
|
||||
#elif defined(__x86_64__)
|
||||
#define MD_JB_SP 4
|
||||
#else
|
||||
#error Unknown CPU architecture
|
||||
#endif
|
||||
|
||||
#define MD_INIT_CONTEXT(_thread, _sp, _main) \
|
||||
ST_BEGIN_MACRO \
|
||||
if (MD_SETJMP((_thread)->context)) \
|
||||
_main(); \
|
||||
*((long *)&((_thread)->context[MD_JB_SP])) = (long) (_sp); \
|
||||
ST_END_MACRO
|
||||
|
||||
#define MD_GET_UTIME() \
|
||||
struct timeval tv; \
|
||||
(void) gettimeofday(&tv, NULL); \
|
||||
return (tv.tv_sec * 1000000LL + tv.tv_usec)
|
||||
|
||||
#elif defined (FREEBSD)
|
||||
|
||||
#define MD_STACK_GROWS_DOWN
|
||||
#define MD_USE_BSD_ANON_MMAP
|
||||
#define MD_ACCEPT_NB_INHERITED
|
||||
#define MD_ALWAYS_UNSERIALIZED_ACCEPT
|
||||
|
||||
#define MD_SETJMP(env) _setjmp(env)
|
||||
#define MD_LONGJMP(env, val) _longjmp(env, val)
|
||||
|
||||
#if defined(__i386__)
|
||||
#define MD_JB_SP 2
|
||||
#elif defined(__alpha__)
|
||||
#define MD_JB_SP 34
|
||||
#elif defined(__amd64__)
|
||||
#define MD_JB_SP 2
|
||||
#else
|
||||
#error Unknown CPU architecture
|
||||
#endif
|
||||
|
||||
#define MD_INIT_CONTEXT(_thread, _sp, _main) \
|
||||
ST_BEGIN_MACRO \
|
||||
if (MD_SETJMP((_thread)->context)) \
|
||||
_main(); \
|
||||
(_thread)->context[0]._jb[MD_JB_SP] = (long) (_sp); \
|
||||
ST_END_MACRO
|
||||
|
||||
#define MD_GET_UTIME() \
|
||||
struct timeval tv; \
|
||||
(void) gettimeofday(&tv, NULL); \
|
||||
return (tv.tv_sec * 1000000LL + tv.tv_usec)
|
||||
|
||||
#elif defined (HPUX)
|
||||
|
||||
#define MD_STACK_GROWS_UP
|
||||
#define MD_USE_BSD_ANON_MMAP
|
||||
#define MD_ACCEPT_NB_INHERITED
|
||||
#define MD_ALWAYS_UNSERIALIZED_ACCEPT
|
||||
|
||||
#define MD_SETJMP(env) _setjmp(env)
|
||||
#define MD_LONGJMP(env, val) _longjmp(env, val)
|
||||
|
||||
#ifndef __LP64__
|
||||
/* 32-bit mode (ILP32 data model) */
|
||||
#define MD_INIT_CONTEXT(_thread, _sp, _main) \
|
||||
ST_BEGIN_MACRO \
|
||||
if (MD_SETJMP((_thread)->context)) \
|
||||
_main(); \
|
||||
((long *)((_thread)->context))[1] = (long) (_sp); \
|
||||
ST_END_MACRO
|
||||
#else
|
||||
/* 64-bit mode (LP64 data model) */
|
||||
#define MD_STACK_PAD_SIZE 256
|
||||
/* Last stack frame must be preserved */
|
||||
#define MD_INIT_CONTEXT(_thread, _sp, _main) \
|
||||
ST_BEGIN_MACRO \
|
||||
if (MD_SETJMP((_thread)->context)) \
|
||||
_main(); \
|
||||
memcpy((char *)(_sp) - MD_STACK_PAD_SIZE, \
|
||||
((char **)((_thread)->context))[1] - MD_STACK_PAD_SIZE, \
|
||||
MD_STACK_PAD_SIZE); \
|
||||
((long *)((_thread)->context))[1] = (long) (_sp); \
|
||||
ST_END_MACRO
|
||||
#endif /* !__LP64__ */
|
||||
|
||||
#define MD_GET_UTIME() \
|
||||
struct timeval tv; \
|
||||
(void) gettimeofday(&tv, NULL); \
|
||||
return (tv.tv_sec * 1000000LL + tv.tv_usec)
|
||||
|
||||
#elif defined (IRIX)
|
||||
|
||||
#include <sys/syssgi.h>
|
||||
|
||||
#define MD_STACK_GROWS_DOWN
|
||||
#define MD_USE_SYSV_ANON_MMAP
|
||||
#define MD_ACCEPT_NB_INHERITED
|
||||
#define MD_ALWAYS_UNSERIALIZED_ACCEPT
|
||||
|
||||
#define MD_SETJMP(env) setjmp(env)
|
||||
#define MD_LONGJMP(env, val) longjmp(env, val)
|
||||
|
||||
#define MD_INIT_CONTEXT(_thread, _sp, _main) \
|
||||
ST_BEGIN_MACRO \
|
||||
(void) MD_SETJMP((_thread)->context); \
|
||||
(_thread)->context[JB_SP] = (long) (_sp); \
|
||||
(_thread)->context[JB_PC] = (long) _main; \
|
||||
ST_END_MACRO
|
||||
|
||||
#define MD_GET_UTIME() \
|
||||
static int inited = 0; \
|
||||
static clockid_t clock_id = CLOCK_SGI_CYCLE; \
|
||||
struct timespec ts; \
|
||||
if (!inited) { \
|
||||
if (syssgi(SGI_CYCLECNTR_SIZE) < 64) \
|
||||
clock_id = CLOCK_REALTIME; \
|
||||
inited = 1; \
|
||||
} \
|
||||
(void) clock_gettime(clock_id, &ts); \
|
||||
return (ts.tv_sec * 1000000LL + ts.tv_nsec / 1000)
|
||||
|
||||
/*
|
||||
* Cap the stack by zeroing out the saved return address register
|
||||
* value. This allows libexc, used by SpeedShop, to know when to stop
|
||||
* backtracing since it won't find main, start, or any other known
|
||||
* stack root function in a state thread's stack. Without this libexc
|
||||
* traces right off the stack and crashes.
|
||||
* The function preamble stores ra at 8(sp), this stores zero there.
|
||||
* N.B. This macro is compiler/ABI dependent. It must change if ANY more
|
||||
* automatic variables are added to the _st_thread_main() routine, because
|
||||
* the address where ra is stored will change.
|
||||
*/
|
||||
#if !defined(__GNUC__) && defined(_MIPS_SIM) && _MIPS_SIM != _ABIO32
|
||||
#define MD_CAP_STACK(var_addr) \
|
||||
(((volatile __uint64_t *)(var_addr))[1] = 0)
|
||||
#endif
|
||||
|
||||
#elif defined (LINUX)
|
||||
|
||||
/*
|
||||
* These are properties of the linux kernel and are the same on every
|
||||
* flavor and architecture.
|
||||
*/
|
||||
#define MD_USE_BSD_ANON_MMAP
|
||||
#define MD_ACCEPT_NB_NOT_INHERITED
|
||||
#define MD_ALWAYS_UNSERIALIZED_ACCEPT
|
||||
/*
|
||||
* Modern GNU/Linux is Posix.1g compliant.
|
||||
*/
|
||||
#define MD_HAVE_SOCKLEN_T
|
||||
|
||||
/*
|
||||
* All architectures and flavors of linux have the gettimeofday
|
||||
* function but if you know of a faster way, use it.
|
||||
*/
|
||||
#define MD_GET_UTIME() \
|
||||
struct timeval tv; \
|
||||
(void) gettimeofday(&tv, NULL); \
|
||||
return (tv.tv_sec * 1000000LL + tv.tv_usec)
|
||||
|
||||
#if defined(__ia64__)
|
||||
#define MD_STACK_GROWS_DOWN
|
||||
|
||||
/*
|
||||
* IA-64 architecture. Besides traditional memory call stack, IA-64
|
||||
* uses general register stack. Thus each thread needs a backing store
|
||||
* for register stack in addition to memory stack. Standard
|
||||
* setjmp()/longjmp() cannot be used for thread context switching
|
||||
* because their implementation implicitly assumes that only one
|
||||
* register stack exists.
|
||||
*/
|
||||
#ifdef USE_LIBC_SETJMP
|
||||
#undef USE_LIBC_SETJMP
|
||||
#endif
|
||||
#define MD_USE_BUILTIN_SETJMP
|
||||
|
||||
#define MD_STACK_PAD_SIZE 128
|
||||
/* Last register stack frame must be preserved */
|
||||
#define MD_INIT_CONTEXT(_thread, _sp, _bsp, _main) \
|
||||
ST_BEGIN_MACRO \
|
||||
if (MD_SETJMP((_thread)->context)) \
|
||||
_main(); \
|
||||
memcpy((char *)(_bsp) - MD_STACK_PAD_SIZE, \
|
||||
(char *)(_thread)->context[0].__jmpbuf[17] - MD_STACK_PAD_SIZE, \
|
||||
MD_STACK_PAD_SIZE); \
|
||||
(_thread)->context[0].__jmpbuf[0] = (long) (_sp); \
|
||||
(_thread)->context[0].__jmpbuf[17] = (long) (_bsp); \
|
||||
ST_END_MACRO
|
||||
|
||||
#elif defined(__mips__)
|
||||
#define MD_STACK_GROWS_DOWN
|
||||
|
||||
#define MD_INIT_CONTEXT(_thread, _sp, _main) \
|
||||
ST_BEGIN_MACRO \
|
||||
MD_SETJMP((_thread)->context); \
|
||||
_thread->context[0].__jmpbuf[0].__pc = (__ptr_t) _main; \
|
||||
_thread->context[0].__jmpbuf[0].__sp = _sp; \
|
||||
ST_END_MACRO
|
||||
|
||||
#else /* Not IA-64 or mips */
|
||||
|
||||
/*
|
||||
* On linux, there are a few styles of jmpbuf format. These vary based
|
||||
* on architecture/glibc combination.
|
||||
*
|
||||
* Most of the glibc based toggles were lifted from:
|
||||
* mozilla/nsprpub/pr/include/md/_linux.h
|
||||
*/
|
||||
|
||||
/*
|
||||
* Starting with glibc 2.4, JB_SP definitions are not public anymore.
|
||||
* They, however, can still be found in glibc source tree in
|
||||
* architecture-specific "jmpbuf-offsets.h" files.
|
||||
* Most importantly, the content of jmp_buf is mangled by setjmp to make
|
||||
* it completely opaque (the mangling can be disabled by setting the
|
||||
* LD_POINTER_GUARD environment variable before application execution).
|
||||
* Therefore we will use built-in _st_md_cxt_save/_st_md_cxt_restore
|
||||
* functions as a setjmp/longjmp replacement wherever they are available
|
||||
* unless USE_LIBC_SETJMP is defined.
|
||||
*/
|
||||
|
||||
#if defined(__powerpc__)
|
||||
#define MD_STACK_GROWS_DOWN
|
||||
|
||||
#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)
|
||||
#ifndef JB_GPR1
|
||||
#define JB_GPR1 0
|
||||
#endif
|
||||
#define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[JB_GPR1]
|
||||
#else
|
||||
/* not an error but certainly cause for caution */
|
||||
#error "Untested use of old glibc on powerpc"
|
||||
#define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[0].__misc[0]
|
||||
#endif /* glibc 2.1 or later */
|
||||
|
||||
#elif defined(__alpha)
|
||||
#define MD_STACK_GROWS_DOWN
|
||||
|
||||
#if defined(__GLIBC__) && __GLIBC__ >= 2
|
||||
#ifndef JB_SP
|
||||
#define JB_SP 8
|
||||
#endif
|
||||
#define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[JB_SP]
|
||||
#else
|
||||
/* not an error but certainly cause for caution */
|
||||
#error "Untested use of old glibc on alpha"
|
||||
#define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[0].__sp
|
||||
#endif
|
||||
|
||||
#elif defined(__mc68000__)
|
||||
#define MD_STACK_GROWS_DOWN
|
||||
|
||||
/* m68k still uses old style sigjmp_buf */
|
||||
#define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[0].__sp
|
||||
|
||||
#elif defined(__sparc__)
|
||||
#define MD_STACK_GROWS_DOWN
|
||||
|
||||
#if defined(__GLIBC__) && __GLIBC__ >= 2
|
||||
#ifndef JB_SP
|
||||
#define JB_SP 0
|
||||
#endif
|
||||
#define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[JB_SP]
|
||||
#else
|
||||
/* not an error but certainly cause for caution */
|
||||
#error "Untested use of old glic on sparc -- also using odd mozilla derived __fp"
|
||||
#define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[0].__fp
|
||||
#endif
|
||||
|
||||
#elif defined(__i386__)
|
||||
#define MD_STACK_GROWS_DOWN
|
||||
#define MD_USE_BUILTIN_SETJMP
|
||||
|
||||
#if defined(__GLIBC__) && __GLIBC__ >= 2
|
||||
#ifndef JB_SP
|
||||
#define JB_SP 4
|
||||
#endif
|
||||
#define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[JB_SP]
|
||||
#else
|
||||
/* not an error but certainly cause for caution */
|
||||
#error "Untested use of old glibc on i386"
|
||||
#define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[0].__sp
|
||||
#endif
|
||||
|
||||
#elif defined(__amd64__) || defined(__x86_64__)
|
||||
#define MD_STACK_GROWS_DOWN
|
||||
#define MD_USE_BUILTIN_SETJMP
|
||||
|
||||
#ifndef JB_RSP
|
||||
#define JB_RSP 6
|
||||
#endif
|
||||
#define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[JB_RSP]
|
||||
|
||||
#elif defined(__aarch64__)
|
||||
/* https://github.com/ossrs/state-threads/issues/9 */
|
||||
#define MD_STACK_GROWS_DOWN
|
||||
#define MD_USE_BUILTIN_SETJMP
|
||||
#define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[13]
|
||||
|
||||
#elif defined(__arm__)
|
||||
#define MD_STACK_GROWS_DOWN
|
||||
/* https://github.com/ossrs/state-threads/issues/1#issuecomment-244648573 */
|
||||
#define MD_USE_BUILTIN_SETJMP
|
||||
|
||||
/* force to use glibc solution, hack the guard jmpbuf from michaeltalyansky */
|
||||
#ifdef USE_LIBC_SETJMP
|
||||
#undef MD_USE_BUILTIN_SETJMP
|
||||
#endif
|
||||
|
||||
#if defined(__GLIBC__) && __GLIBC__ >= 2
|
||||
/* Merge from https://github.com/michaeltalyansky/state-threads/commit/56554a5c425aee8e7a73782eae23d74d83c4120a */
|
||||
#define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[8]
|
||||
#else
|
||||
#error "ARM/Linux pre-glibc2 not supported yet"
|
||||
#endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */
|
||||
|
||||
#elif defined(__s390__)
|
||||
#define MD_STACK_GROWS_DOWN
|
||||
|
||||
/* There is no JB_SP in glibc at this time. (glibc 2.2.5)
|
||||
*/
|
||||
#define MD_GET_SP(_t) (_t)->context[0].__jmpbuf[0].__gregs[9]
|
||||
|
||||
#elif defined(__hppa__)
|
||||
#define MD_STACK_GROWS_UP
|
||||
|
||||
/* yes, this is gross, unfortunately at the moment (2002/08/01) there is
|
||||
* a bug in hppa's glibc header definition for JB_SP, so we can't
|
||||
* use that...
|
||||
*/
|
||||
#define MD_GET_SP(_t) (*(long *)(((char *)&(_t)->context[0].__jmpbuf[0]) + 76))
|
||||
|
||||
#else
|
||||
#error "Unknown CPU architecture"
|
||||
#endif /* Cases with common MD_INIT_CONTEXT and different SP locations */
|
||||
|
||||
#define MD_INIT_CONTEXT(_thread, _sp, _main) \
|
||||
ST_BEGIN_MACRO \
|
||||
if (MD_SETJMP((_thread)->context)) \
|
||||
_main(); \
|
||||
MD_GET_SP(_thread) = (long) (_sp); \
|
||||
ST_END_MACRO
|
||||
|
||||
#endif /* Cases with different MD_INIT_CONTEXT */
|
||||
|
||||
#if defined(MD_USE_BUILTIN_SETJMP) && !defined(USE_LIBC_SETJMP)
|
||||
#define MD_SETJMP(env) _st_md_cxt_save(env)
|
||||
#define MD_LONGJMP(env, val) _st_md_cxt_restore(env, val)
|
||||
|
||||
extern int _st_md_cxt_save(jmp_buf env);
|
||||
extern void _st_md_cxt_restore(jmp_buf env, int val);
|
||||
#else
|
||||
#define MD_SETJMP(env) setjmp(env)
|
||||
#define MD_LONGJMP(env, val) longjmp(env, val)
|
||||
#endif
|
||||
|
||||
#elif defined (NETBSD)
|
||||
|
||||
#define MD_STACK_GROWS_DOWN
|
||||
#define MD_USE_BSD_ANON_MMAP
|
||||
#define MD_ACCEPT_NB_INHERITED
|
||||
#define MD_ALWAYS_UNSERIALIZED_ACCEPT
|
||||
#define MD_HAVE_SOCKLEN_T
|
||||
|
||||
#define MD_SETJMP(env) _setjmp(env)
|
||||
#define MD_LONGJMP(env, val) _longjmp(env, val)
|
||||
|
||||
#if defined(__i386__)
|
||||
#define MD_JB_SP 2
|
||||
#elif defined(__alpha__)
|
||||
#define MD_JB_SP 34
|
||||
#elif defined(__sparc__)
|
||||
#define MD_JB_SP 0
|
||||
#elif defined(__vax__)
|
||||
#define MD_JB_SP 2
|
||||
#else
|
||||
#error Unknown CPU architecture
|
||||
#endif
|
||||
|
||||
#define MD_INIT_CONTEXT(_thread, _sp, _main) \
|
||||
ST_BEGIN_MACRO \
|
||||
if (MD_SETJMP((_thread)->context)) \
|
||||
_main(); \
|
||||
(_thread)->context[MD_JB_SP] = (long) (_sp); \
|
||||
ST_END_MACRO
|
||||
|
||||
#define MD_GET_UTIME() \
|
||||
struct timeval tv; \
|
||||
(void) gettimeofday(&tv, NULL); \
|
||||
return (tv.tv_sec * 1000000LL + tv.tv_usec)
|
||||
|
||||
#elif defined (OPENBSD)
|
||||
|
||||
#define MD_STACK_GROWS_DOWN
|
||||
#define MD_USE_BSD_ANON_MMAP
|
||||
#define MD_ACCEPT_NB_INHERITED
|
||||
#define MD_ALWAYS_UNSERIALIZED_ACCEPT
|
||||
|
||||
#define MD_SETJMP(env) _setjmp(env)
|
||||
#define MD_LONGJMP(env, val) _longjmp(env, val)
|
||||
|
||||
#if defined(__i386__)
|
||||
#define MD_JB_SP 2
|
||||
#elif defined(__alpha__)
|
||||
#define MD_JB_SP 34
|
||||
#elif defined(__sparc__)
|
||||
#define MD_JB_SP 0
|
||||
#elif defined(__amd64__)
|
||||
#define MD_JB_SP 6
|
||||
#else
|
||||
#error Unknown CPU architecture
|
||||
#endif
|
||||
|
||||
#define MD_INIT_CONTEXT(_thread, _sp, _main) \
|
||||
ST_BEGIN_MACRO \
|
||||
if (MD_SETJMP((_thread)->context)) \
|
||||
_main(); \
|
||||
(_thread)->context[MD_JB_SP] = (long) (_sp); \
|
||||
ST_END_MACRO
|
||||
|
||||
#define MD_GET_UTIME() \
|
||||
struct timeval tv; \
|
||||
(void) gettimeofday(&tv, NULL); \
|
||||
return (tv.tv_sec * 1000000LL + tv.tv_usec)
|
||||
|
||||
#elif defined (OSF1)
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#define MD_STACK_GROWS_DOWN
|
||||
#define MD_USE_SYSV_ANON_MMAP
|
||||
#define MD_ACCEPT_NB_NOT_INHERITED
|
||||
#define MD_ALWAYS_UNSERIALIZED_ACCEPT
|
||||
|
||||
#define MD_SETJMP(env) _setjmp(env)
|
||||
#define MD_LONGJMP(env, val) _longjmp(env, val)
|
||||
|
||||
#define MD_INIT_CONTEXT(_thread, _sp, _main) \
|
||||
ST_BEGIN_MACRO \
|
||||
if (MD_SETJMP((_thread)->context)) \
|
||||
_main(); \
|
||||
((struct sigcontext *)((_thread)->context))->sc_sp = (long) (_sp); \
|
||||
ST_END_MACRO
|
||||
|
||||
#define MD_GET_UTIME() \
|
||||
struct timeval tv; \
|
||||
(void) gettimeofday(&tv, NULL); \
|
||||
return (tv.tv_sec * 1000000LL + tv.tv_usec)
|
||||
|
||||
#elif defined (SOLARIS)
|
||||
|
||||
#include <sys/filio.h>
|
||||
extern int getpagesize(void);
|
||||
|
||||
#define MD_STACK_GROWS_DOWN
|
||||
#define MD_USE_SYSV_ANON_MMAP
|
||||
#define MD_ACCEPT_NB_NOT_INHERITED
|
||||
|
||||
#define MD_SETJMP(env) setjmp(env)
|
||||
#define MD_LONGJMP(env, val) longjmp(env, val)
|
||||
|
||||
#if defined(sparc) || defined(__sparc)
|
||||
#ifdef _LP64
|
||||
#define MD_STACK_PAD_SIZE 4095
|
||||
#endif
|
||||
#define MD_INIT_CONTEXT(_thread, _sp, _main) \
|
||||
ST_BEGIN_MACRO \
|
||||
(void) MD_SETJMP((_thread)->context); \
|
||||
(_thread)->context[1] = (long) (_sp); \
|
||||
(_thread)->context[2] = (long) _main; \
|
||||
ST_END_MACRO
|
||||
#elif defined(i386) || defined(__i386)
|
||||
#define MD_INIT_CONTEXT(_thread, _sp, _main) \
|
||||
ST_BEGIN_MACRO \
|
||||
(void) MD_SETJMP((_thread)->context); \
|
||||
(_thread)->context[4] = (long) (_sp); \
|
||||
(_thread)->context[5] = (long) _main; \
|
||||
ST_END_MACRO
|
||||
#elif defined(__amd64__)
|
||||
#define MD_INIT_CONTEXT(_thread, _sp, _main) \
|
||||
ST_BEGIN_MACRO \
|
||||
if (MD_SETJMP((_thread)->context)) \
|
||||
_main(); \
|
||||
(_thread)->context[6] = (long) (_sp); \
|
||||
ST_END_MACRO
|
||||
#else
|
||||
#error Unknown CPU architecture
|
||||
#endif
|
||||
|
||||
#define MD_GET_UTIME() \
|
||||
return (gethrtime() / 1000)
|
||||
|
||||
#else
|
||||
#error Unknown OS
|
||||
#endif /* OS */
|
||||
|
||||
#if !defined(MD_HAVE_POLL) && !defined(MD_DONT_HAVE_POLL)
|
||||
#define MD_HAVE_POLL
|
||||
#endif
|
||||
|
||||
#ifndef MD_STACK_PAD_SIZE
|
||||
#define MD_STACK_PAD_SIZE 128
|
||||
#endif
|
||||
|
||||
#if !defined(MD_HAVE_SOCKLEN_T) && !defined(socklen_t)
|
||||
#define socklen_t int
|
||||
#endif
|
||||
|
||||
#ifndef MD_CAP_STACK
|
||||
#define MD_CAP_STACK(var_addr)
|
||||
#endif
|
||||
|
||||
#endif /* !__ST_MD_H__ */
|
||||
|
45
trunk/3rdparty/st-srs/osguess.sh
vendored
Normal file
45
trunk/3rdparty/st-srs/osguess.sh
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
#
|
||||
# This script can be used to automatically guess target OS.
|
||||
# It requires the config.guess utility which is a part of GNU Autoconf.
|
||||
# GNU Autoconf can be downloaded from ftp://ftp.gnu.org/gnu/autoconf/
|
||||
#
|
||||
# Use "default" as a make target for automatic builds.
|
||||
#
|
||||
|
||||
|
||||
# Specify path to the config.guess utility (unless set via environment)
|
||||
#CONFIG_GUESS_PATH=
|
||||
|
||||
|
||||
if [ x"$CONFIG_GUESS_PATH" = x ]; then
|
||||
echo "Error: CONFIG_GUESS_PATH variable is not set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$CONFIG_GUESS_PATH/config.guess" ]; then
|
||||
echo "Can't find $CONFIG_GUESS_PATH/config.guess utility. Wrong path?"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
sys_info=`/bin/sh $CONFIG_GUESS_PATH/config.guess`
|
||||
|
||||
echo "Building for $sys_info"
|
||||
|
||||
case "$sys_info" in
|
||||
*-ibm-aix4* ) OS=AIX ;;
|
||||
*-freebsd* ) OS=FREEBSD ;;
|
||||
hppa*-hp-hpux11*) OS=HPUX ;;
|
||||
*-sgi-irix6* ) OS=IRIX ;;
|
||||
*-linux* ) OS=LINUX ;;
|
||||
*-netbsd* ) OS=NETBSD ;;
|
||||
*-openbsd* ) OS=OPENBSD ;;
|
||||
*-dec-osf* ) OS=OSF1 ;;
|
||||
*-solaris2* ) OS=SOLARIS ;;
|
||||
*-darwin* ) OS=DARWIN ;;
|
||||
* ) OS=
|
||||
echo "Sorry, unsupported OS"
|
||||
exit 1 ;;
|
||||
esac
|
||||
|
||||
echo "Making with OS=$OS"
|
||||
|
166
trunk/3rdparty/st-srs/public.h
vendored
Normal file
166
trunk/3rdparty/st-srs/public.h
vendored
Normal file
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape Portable Runtime library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Silicon Graphics, Inc.
|
||||
*
|
||||
* Portions created by SGI are Copyright (C) 2000-2001 Silicon
|
||||
* Graphics, Inc. All Rights Reserved.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
#ifndef __ST_THREAD_H__
|
||||
#define __ST_THREAD_H__
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <poll.h>
|
||||
|
||||
#define ST_VERSION "1.9"
|
||||
#define ST_VERSION_MAJOR 1
|
||||
#define ST_VERSION_MINOR 9
|
||||
|
||||
/* Undefine this to remove the context switch callback feature. */
|
||||
#define ST_SWITCH_CB
|
||||
|
||||
#ifndef ETIME
|
||||
#define ETIME ETIMEDOUT
|
||||
#endif
|
||||
|
||||
#ifndef ST_UTIME_NO_TIMEOUT
|
||||
#define ST_UTIME_NO_TIMEOUT ((st_utime_t) -1LL)
|
||||
#endif
|
||||
|
||||
#ifndef ST_UTIME_NO_WAIT
|
||||
#define ST_UTIME_NO_WAIT 0
|
||||
#endif
|
||||
|
||||
#define ST_EVENTSYS_DEFAULT 0
|
||||
#define ST_EVENTSYS_SELECT 1
|
||||
#define ST_EVENTSYS_POLL 2
|
||||
#define ST_EVENTSYS_ALT 3
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef unsigned long long st_utime_t;
|
||||
typedef struct _st_thread * st_thread_t;
|
||||
typedef struct _st_cond * st_cond_t;
|
||||
typedef struct _st_mutex * st_mutex_t;
|
||||
typedef struct _st_netfd * st_netfd_t;
|
||||
#ifdef ST_SWITCH_CB
|
||||
typedef void (*st_switch_cb_t)(void);
|
||||
#endif
|
||||
|
||||
extern int st_init(void);
|
||||
extern int st_getfdlimit(void);
|
||||
|
||||
extern int st_set_eventsys(int eventsys);
|
||||
extern int st_get_eventsys(void);
|
||||
extern const char *st_get_eventsys_name(void);
|
||||
|
||||
#ifdef ST_SWITCH_CB
|
||||
extern st_switch_cb_t st_set_switch_in_cb(st_switch_cb_t cb);
|
||||
extern st_switch_cb_t st_set_switch_out_cb(st_switch_cb_t cb);
|
||||
#endif
|
||||
|
||||
extern st_thread_t st_thread_self(void);
|
||||
extern void st_thread_exit(void *retval);
|
||||
extern int st_thread_join(st_thread_t thread, void **retvalp);
|
||||
extern void st_thread_interrupt(st_thread_t thread);
|
||||
extern st_thread_t st_thread_create(void *(*start)(void *arg), void *arg, int joinable, int stack_size);
|
||||
extern int st_randomize_stacks(int on);
|
||||
extern int st_set_utime_function(st_utime_t (*func)(void));
|
||||
|
||||
extern st_utime_t st_utime(void);
|
||||
extern st_utime_t st_utime_last_clock(void);
|
||||
extern int st_timecache_set(int on);
|
||||
extern time_t st_time(void);
|
||||
extern int st_usleep(st_utime_t usecs);
|
||||
extern int st_sleep(int secs);
|
||||
extern st_cond_t st_cond_new(void);
|
||||
extern int st_cond_destroy(st_cond_t cvar);
|
||||
extern int st_cond_timedwait(st_cond_t cvar, st_utime_t timeout);
|
||||
extern int st_cond_wait(st_cond_t cvar);
|
||||
extern int st_cond_signal(st_cond_t cvar);
|
||||
extern int st_cond_broadcast(st_cond_t cvar);
|
||||
extern st_mutex_t st_mutex_new(void);
|
||||
extern int st_mutex_destroy(st_mutex_t lock);
|
||||
extern int st_mutex_lock(st_mutex_t lock);
|
||||
extern int st_mutex_unlock(st_mutex_t lock);
|
||||
extern int st_mutex_trylock(st_mutex_t lock);
|
||||
|
||||
extern int st_key_create(int *keyp, void (*destructor)(void *));
|
||||
extern int st_key_getlimit(void);
|
||||
extern int st_thread_setspecific(int key, void *value);
|
||||
extern void *st_thread_getspecific(int key);
|
||||
|
||||
extern st_netfd_t st_netfd_open(int osfd);
|
||||
extern st_netfd_t st_netfd_open_socket(int osfd);
|
||||
extern void st_netfd_free(st_netfd_t fd);
|
||||
extern int st_netfd_close(st_netfd_t fd);
|
||||
extern int st_netfd_fileno(st_netfd_t fd);
|
||||
extern void st_netfd_setspecific(st_netfd_t fd, void *value, void (*destructor)(void *));
|
||||
extern void *st_netfd_getspecific(st_netfd_t fd);
|
||||
extern int st_netfd_serialize_accept(st_netfd_t fd);
|
||||
extern int st_netfd_poll(st_netfd_t fd, int how, st_utime_t timeout);
|
||||
|
||||
extern int st_poll(struct pollfd *pds, int npds, st_utime_t timeout);
|
||||
extern st_netfd_t st_accept(st_netfd_t fd, struct sockaddr *addr, int *addrlen, st_utime_t timeout);
|
||||
extern int st_connect(st_netfd_t fd, const struct sockaddr *addr, int addrlen, st_utime_t timeout);
|
||||
extern ssize_t st_read(st_netfd_t fd, void *buf, size_t nbyte, st_utime_t timeout);
|
||||
extern ssize_t st_read_fully(st_netfd_t fd, void *buf, size_t nbyte, st_utime_t timeout);
|
||||
extern int st_read_resid(st_netfd_t fd, void *buf, size_t *resid, st_utime_t timeout);
|
||||
extern ssize_t st_readv(st_netfd_t fd, const struct iovec *iov, int iov_size, st_utime_t timeout);
|
||||
extern int st_readv_resid(st_netfd_t fd, struct iovec **iov, int *iov_size, st_utime_t timeout);
|
||||
extern ssize_t st_write(st_netfd_t fd, const void *buf, size_t nbyte, st_utime_t timeout);
|
||||
extern int st_write_resid(st_netfd_t fd, const void *buf, size_t *resid, st_utime_t timeout);
|
||||
extern ssize_t st_writev(st_netfd_t fd, const struct iovec *iov, int iov_size, st_utime_t timeout);
|
||||
extern int st_writev_resid(st_netfd_t fd, struct iovec **iov, int *iov_size, st_utime_t timeout);
|
||||
extern int st_recvfrom(st_netfd_t fd, void *buf, int len, struct sockaddr *from, int *fromlen, st_utime_t timeout);
|
||||
extern int st_sendto(st_netfd_t fd, const void *msg, int len, const struct sockaddr *to, int tolen, st_utime_t timeout);
|
||||
extern int st_recvmsg(st_netfd_t fd, struct msghdr *msg, int flags, st_utime_t timeout);
|
||||
extern int st_sendmsg(st_netfd_t fd, const struct msghdr *msg, int flags, st_utime_t timeout);
|
||||
extern st_netfd_t st_open(const char *path, int oflags, mode_t mode);
|
||||
|
||||
#ifdef DEBUG
|
||||
extern void _st_show_thread_stack(st_thread_t thread, const char *messg);
|
||||
extern void _st_iterate_threads(void);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !__ST_THREAD_H__ */
|
||||
|
705
trunk/3rdparty/st-srs/sched.c
vendored
Normal file
705
trunk/3rdparty/st-srs/sched.c
vendored
Normal file
|
@ -0,0 +1,705 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape Portable Runtime library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Silicon Graphics, Inc.
|
||||
*
|
||||
* Portions created by SGI are Copyright (C) 2000-2001 Silicon
|
||||
* Graphics, Inc. All Rights Reserved.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is derived directly from Netscape Communications Corporation,
|
||||
* and consists of extensive modifications made during the year(s) 1999-2000.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include "common.h"
|
||||
|
||||
/* merge from https://github.com/toffaletti/state-threads/commit/7f57fc9acc05e657bca1223f1e5b9b1a45ed929b */
|
||||
#ifndef NVALGRIND
|
||||
#include <valgrind/valgrind.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* Global data */
|
||||
_st_vp_t _st_this_vp; /* This VP */
|
||||
_st_thread_t *_st_this_thread; /* Current thread */
|
||||
int _st_active_count = 0; /* Active thread count */
|
||||
|
||||
time_t _st_curr_time = 0; /* Current time as returned by time(2) */
|
||||
st_utime_t _st_last_tset; /* Last time it was fetched */
|
||||
|
||||
|
||||
int st_poll(struct pollfd *pds, int npds, st_utime_t timeout)
|
||||
{
|
||||
struct pollfd *pd;
|
||||
struct pollfd *epd = pds + npds;
|
||||
_st_pollq_t pq;
|
||||
_st_thread_t *me = _ST_CURRENT_THREAD();
|
||||
int n;
|
||||
|
||||
if (me->flags & _ST_FL_INTERRUPT) {
|
||||
me->flags &= ~_ST_FL_INTERRUPT;
|
||||
errno = EINTR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((*_st_eventsys->pollset_add)(pds, npds) < 0)
|
||||
return -1;
|
||||
|
||||
pq.pds = pds;
|
||||
pq.npds = npds;
|
||||
pq.thread = me;
|
||||
pq.on_ioq = 1;
|
||||
_ST_ADD_IOQ(pq);
|
||||
if (timeout != ST_UTIME_NO_TIMEOUT)
|
||||
_ST_ADD_SLEEPQ(me, timeout);
|
||||
me->state = _ST_ST_IO_WAIT;
|
||||
|
||||
_ST_SWITCH_CONTEXT(me);
|
||||
|
||||
n = 0;
|
||||
if (pq.on_ioq) {
|
||||
/* If we timed out, the pollq might still be on the ioq. Remove it */
|
||||
_ST_DEL_IOQ(pq);
|
||||
(*_st_eventsys->pollset_del)(pds, npds);
|
||||
} else {
|
||||
/* Count the number of ready descriptors */
|
||||
for (pd = pds; pd < epd; pd++) {
|
||||
if (pd->revents)
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
if (me->flags & _ST_FL_INTERRUPT) {
|
||||
me->flags &= ~_ST_FL_INTERRUPT;
|
||||
errno = EINTR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
void _st_vp_schedule(void)
|
||||
{
|
||||
_st_thread_t *thread;
|
||||
|
||||
if (_ST_RUNQ.next != &_ST_RUNQ) {
|
||||
/* Pull thread off of the run queue */
|
||||
thread = _ST_THREAD_PTR(_ST_RUNQ.next);
|
||||
_ST_DEL_RUNQ(thread);
|
||||
} else {
|
||||
/* If there are no threads to run, switch to the idle thread */
|
||||
thread = _st_this_vp.idle_thread;
|
||||
}
|
||||
ST_ASSERT(thread->state == _ST_ST_RUNNABLE);
|
||||
|
||||
/* Resume the thread */
|
||||
thread->state = _ST_ST_RUNNING;
|
||||
_ST_RESTORE_CONTEXT(thread);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initialize this Virtual Processor
|
||||
*/
|
||||
int st_init(void)
|
||||
{
|
||||
_st_thread_t *thread;
|
||||
|
||||
if (_st_active_count) {
|
||||
/* Already initialized */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* We can ignore return value here */
|
||||
st_set_eventsys(ST_EVENTSYS_DEFAULT);
|
||||
|
||||
if (_st_io_init() < 0)
|
||||
return -1;
|
||||
|
||||
memset(&_st_this_vp, 0, sizeof(_st_vp_t));
|
||||
|
||||
ST_INIT_CLIST(&_ST_RUNQ);
|
||||
ST_INIT_CLIST(&_ST_IOQ);
|
||||
ST_INIT_CLIST(&_ST_ZOMBIEQ);
|
||||
#ifdef DEBUG
|
||||
ST_INIT_CLIST(&_ST_THREADQ);
|
||||
#endif
|
||||
|
||||
if ((*_st_eventsys->init)() < 0)
|
||||
return -1;
|
||||
|
||||
_st_this_vp.pagesize = getpagesize();
|
||||
_st_this_vp.last_clock = st_utime();
|
||||
|
||||
/*
|
||||
* Create idle thread
|
||||
*/
|
||||
_st_this_vp.idle_thread = st_thread_create(_st_idle_thread_start, NULL, 0, 0);
|
||||
if (!_st_this_vp.idle_thread)
|
||||
return -1;
|
||||
_st_this_vp.idle_thread->flags = _ST_FL_IDLE_THREAD;
|
||||
_st_active_count--;
|
||||
_ST_DEL_RUNQ(_st_this_vp.idle_thread);
|
||||
|
||||
/*
|
||||
* Initialize primordial thread
|
||||
*/
|
||||
thread = (_st_thread_t *) calloc(1, sizeof(_st_thread_t) + (ST_KEYS_MAX * sizeof(void *)));
|
||||
if (!thread)
|
||||
return -1;
|
||||
thread->private_data = (void **) (thread + 1);
|
||||
thread->state = _ST_ST_RUNNING;
|
||||
thread->flags = _ST_FL_PRIMORDIAL;
|
||||
_ST_SET_CURRENT_THREAD(thread);
|
||||
_st_active_count++;
|
||||
#ifdef DEBUG
|
||||
_ST_ADD_THREADQ(thread);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef ST_SWITCH_CB
|
||||
st_switch_cb_t st_set_switch_in_cb(st_switch_cb_t cb)
|
||||
{
|
||||
st_switch_cb_t ocb = _st_this_vp.switch_in_cb;
|
||||
_st_this_vp.switch_in_cb = cb;
|
||||
return ocb;
|
||||
}
|
||||
|
||||
st_switch_cb_t st_set_switch_out_cb(st_switch_cb_t cb)
|
||||
{
|
||||
st_switch_cb_t ocb = _st_this_vp.switch_out_cb;
|
||||
_st_this_vp.switch_out_cb = cb;
|
||||
return ocb;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Start function for the idle thread
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
void *_st_idle_thread_start(void *arg)
|
||||
{
|
||||
_st_thread_t *me = _ST_CURRENT_THREAD();
|
||||
|
||||
while (_st_active_count > 0) {
|
||||
/* Idle vp till I/O is ready or the smallest timeout expired */
|
||||
_ST_VP_IDLE();
|
||||
|
||||
/* Check sleep queue for expired threads */
|
||||
_st_vp_check_clock();
|
||||
|
||||
me->state = _ST_ST_RUNNABLE;
|
||||
_ST_SWITCH_CONTEXT(me);
|
||||
}
|
||||
|
||||
/* No more threads */
|
||||
exit(0);
|
||||
|
||||
/* NOTREACHED */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void st_thread_exit(void *retval)
|
||||
{
|
||||
_st_thread_t *thread = _ST_CURRENT_THREAD();
|
||||
|
||||
thread->retval = retval;
|
||||
_st_thread_cleanup(thread);
|
||||
_st_active_count--;
|
||||
if (thread->term) {
|
||||
/* Put thread on the zombie queue */
|
||||
thread->state = _ST_ST_ZOMBIE;
|
||||
_ST_ADD_ZOMBIEQ(thread);
|
||||
|
||||
/* Notify on our termination condition variable */
|
||||
st_cond_signal(thread->term);
|
||||
|
||||
/* Switch context and come back later */
|
||||
_ST_SWITCH_CONTEXT(thread);
|
||||
|
||||
/* Continue the cleanup */
|
||||
st_cond_destroy(thread->term);
|
||||
thread->term = NULL;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
_ST_DEL_THREADQ(thread);
|
||||
#endif
|
||||
|
||||
/* merge from https://github.com/toffaletti/state-threads/commit/7f57fc9acc05e657bca1223f1e5b9b1a45ed929b */
|
||||
#ifndef NVALGRIND
|
||||
if (!(thread->flags & _ST_FL_PRIMORDIAL)) {
|
||||
VALGRIND_STACK_DEREGISTER(thread->stack->valgrind_stack_id);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!(thread->flags & _ST_FL_PRIMORDIAL))
|
||||
_st_stack_free(thread->stack);
|
||||
|
||||
/* Find another thread to run */
|
||||
_ST_SWITCH_CONTEXT(thread);
|
||||
/* Not going to land here */
|
||||
}
|
||||
|
||||
|
||||
int st_thread_join(_st_thread_t *thread, void **retvalp)
|
||||
{
|
||||
_st_cond_t *term = thread->term;
|
||||
|
||||
/* Can't join a non-joinable thread */
|
||||
if (term == NULL) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
if (_ST_CURRENT_THREAD() == thread) {
|
||||
errno = EDEADLK;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Multiple threads can't wait on the same joinable thread */
|
||||
if (term->wait_q.next != &term->wait_q) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (thread->state != _ST_ST_ZOMBIE) {
|
||||
if (st_cond_timedwait(term, ST_UTIME_NO_TIMEOUT) != 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (retvalp)
|
||||
*retvalp = thread->retval;
|
||||
|
||||
/*
|
||||
* Remove target thread from the zombie queue and make it runnable.
|
||||
* When it gets scheduled later, it will do the clean up.
|
||||
*/
|
||||
thread->state = _ST_ST_RUNNABLE;
|
||||
_ST_DEL_ZOMBIEQ(thread);
|
||||
_ST_ADD_RUNQ(thread);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void _st_thread_main(void)
|
||||
{
|
||||
_st_thread_t *thread = _ST_CURRENT_THREAD();
|
||||
|
||||
/*
|
||||
* Cap the stack by zeroing out the saved return address register
|
||||
* value. This allows some debugging/profiling tools to know when
|
||||
* to stop unwinding the stack. It's a no-op on most platforms.
|
||||
*/
|
||||
MD_CAP_STACK(&thread);
|
||||
|
||||
/* Run thread main */
|
||||
thread->retval = (*thread->start)(thread->arg);
|
||||
|
||||
/* All done, time to go away */
|
||||
st_thread_exit(thread->retval);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Insert "thread" into the timeout heap, in the position
|
||||
* specified by thread->heap_index. See docs/timeout_heap.txt
|
||||
* for details about the timeout heap.
|
||||
*/
|
||||
static _st_thread_t **heap_insert(_st_thread_t *thread) {
|
||||
int target = thread->heap_index;
|
||||
int s = target;
|
||||
_st_thread_t **p = &_ST_SLEEPQ;
|
||||
int bits = 0;
|
||||
int bit;
|
||||
int index = 1;
|
||||
|
||||
while (s) {
|
||||
s >>= 1;
|
||||
bits++;
|
||||
}
|
||||
for (bit = bits - 2; bit >= 0; bit--) {
|
||||
if (thread->due < (*p)->due) {
|
||||
_st_thread_t *t = *p;
|
||||
thread->left = t->left;
|
||||
thread->right = t->right;
|
||||
*p = thread;
|
||||
thread->heap_index = index;
|
||||
thread = t;
|
||||
}
|
||||
index <<= 1;
|
||||
if (target & (1 << bit)) {
|
||||
p = &((*p)->right);
|
||||
index |= 1;
|
||||
} else {
|
||||
p = &((*p)->left);
|
||||
}
|
||||
}
|
||||
thread->heap_index = index;
|
||||
*p = thread;
|
||||
thread->left = thread->right = NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Delete "thread" from the timeout heap.
|
||||
*/
|
||||
static void heap_delete(_st_thread_t *thread) {
|
||||
_st_thread_t *t, **p;
|
||||
int bits = 0;
|
||||
int s, bit;
|
||||
|
||||
/* First find and unlink the last heap element */
|
||||
p = &_ST_SLEEPQ;
|
||||
s = _ST_SLEEPQ_SIZE;
|
||||
while (s) {
|
||||
s >>= 1;
|
||||
bits++;
|
||||
}
|
||||
for (bit = bits - 2; bit >= 0; bit--) {
|
||||
if (_ST_SLEEPQ_SIZE & (1 << bit)) {
|
||||
p = &((*p)->right);
|
||||
} else {
|
||||
p = &((*p)->left);
|
||||
}
|
||||
}
|
||||
t = *p;
|
||||
*p = NULL;
|
||||
--_ST_SLEEPQ_SIZE;
|
||||
if (t != thread) {
|
||||
/*
|
||||
* Insert the unlinked last element in place of the element we are deleting
|
||||
*/
|
||||
t->heap_index = thread->heap_index;
|
||||
p = heap_insert(t);
|
||||
t = *p;
|
||||
t->left = thread->left;
|
||||
t->right = thread->right;
|
||||
|
||||
/*
|
||||
* Reestablish the heap invariant.
|
||||
*/
|
||||
for (;;) {
|
||||
_st_thread_t *y; /* The younger child */
|
||||
int index_tmp;
|
||||
if (t->left == NULL)
|
||||
break;
|
||||
else if (t->right == NULL)
|
||||
y = t->left;
|
||||
else if (t->left->due < t->right->due)
|
||||
y = t->left;
|
||||
else
|
||||
y = t->right;
|
||||
if (t->due > y->due) {
|
||||
_st_thread_t *tl = y->left;
|
||||
_st_thread_t *tr = y->right;
|
||||
*p = y;
|
||||
if (y == t->left) {
|
||||
y->left = t;
|
||||
y->right = t->right;
|
||||
p = &y->left;
|
||||
} else {
|
||||
y->left = t->left;
|
||||
y->right = t;
|
||||
p = &y->right;
|
||||
}
|
||||
t->left = tl;
|
||||
t->right = tr;
|
||||
index_tmp = t->heap_index;
|
||||
t->heap_index = y->heap_index;
|
||||
y->heap_index = index_tmp;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
thread->left = thread->right = NULL;
|
||||
}
|
||||
|
||||
|
||||
void _st_add_sleep_q(_st_thread_t *thread, st_utime_t timeout)
|
||||
{
|
||||
thread->due = _ST_LAST_CLOCK + timeout;
|
||||
thread->flags |= _ST_FL_ON_SLEEPQ;
|
||||
thread->heap_index = ++_ST_SLEEPQ_SIZE;
|
||||
heap_insert(thread);
|
||||
}
|
||||
|
||||
|
||||
void _st_del_sleep_q(_st_thread_t *thread)
|
||||
{
|
||||
heap_delete(thread);
|
||||
thread->flags &= ~_ST_FL_ON_SLEEPQ;
|
||||
}
|
||||
|
||||
|
||||
void _st_vp_check_clock(void)
|
||||
{
|
||||
_st_thread_t *thread;
|
||||
st_utime_t elapsed, now;
|
||||
|
||||
now = st_utime();
|
||||
elapsed = now - _ST_LAST_CLOCK;
|
||||
_ST_LAST_CLOCK = now;
|
||||
|
||||
if (_st_curr_time && now - _st_last_tset > 999000) {
|
||||
_st_curr_time = time(NULL);
|
||||
_st_last_tset = now;
|
||||
}
|
||||
|
||||
while (_ST_SLEEPQ != NULL) {
|
||||
thread = _ST_SLEEPQ;
|
||||
ST_ASSERT(thread->flags & _ST_FL_ON_SLEEPQ);
|
||||
if (thread->due > now)
|
||||
break;
|
||||
_ST_DEL_SLEEPQ(thread);
|
||||
|
||||
/* If thread is waiting on condition variable, set the time out flag */
|
||||
if (thread->state == _ST_ST_COND_WAIT)
|
||||
thread->flags |= _ST_FL_TIMEDOUT;
|
||||
|
||||
/* Make thread runnable */
|
||||
ST_ASSERT(!(thread->flags & _ST_FL_IDLE_THREAD));
|
||||
thread->state = _ST_ST_RUNNABLE;
|
||||
_ST_ADD_RUNQ(thread);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void st_thread_interrupt(_st_thread_t *thread)
|
||||
{
|
||||
/* If thread is already dead */
|
||||
if (thread->state == _ST_ST_ZOMBIE)
|
||||
return;
|
||||
|
||||
thread->flags |= _ST_FL_INTERRUPT;
|
||||
|
||||
if (thread->state == _ST_ST_RUNNING || thread->state == _ST_ST_RUNNABLE)
|
||||
return;
|
||||
|
||||
if (thread->flags & _ST_FL_ON_SLEEPQ)
|
||||
_ST_DEL_SLEEPQ(thread);
|
||||
|
||||
/* Make thread runnable */
|
||||
thread->state = _ST_ST_RUNNABLE;
|
||||
_ST_ADD_RUNQ(thread);
|
||||
}
|
||||
|
||||
|
||||
/* Merge from https://github.com/michaeltalyansky/state-threads/commit/cce736426c2320ffec7c9820df49ee7a18ae638c */
|
||||
#if defined(__arm__) && !defined(MD_USE_BUILTIN_SETJMP) && __GLIBC_MINOR__ >= 19
|
||||
extern unsigned long __pointer_chk_guard;
|
||||
#define PTR_MANGLE(var) \
|
||||
(var) = (__typeof (var)) ((unsigned long) (var) ^ __pointer_chk_guard)
|
||||
#define PTR_DEMANGLE(var) PTR_MANGLE (var)
|
||||
#endif
|
||||
|
||||
|
||||
_st_thread_t *st_thread_create(void *(*start)(void *arg), void *arg, int joinable, int stk_size)
|
||||
{
|
||||
_st_thread_t *thread;
|
||||
_st_stack_t *stack;
|
||||
void **ptds;
|
||||
char *sp;
|
||||
#ifdef __ia64__
|
||||
char *bsp;
|
||||
#endif
|
||||
|
||||
/* Adjust stack size */
|
||||
if (stk_size == 0)
|
||||
stk_size = ST_DEFAULT_STACK_SIZE;
|
||||
stk_size = ((stk_size + _ST_PAGE_SIZE - 1) / _ST_PAGE_SIZE) * _ST_PAGE_SIZE;
|
||||
stack = _st_stack_new(stk_size);
|
||||
if (!stack)
|
||||
return NULL;
|
||||
|
||||
/* Allocate thread object and per-thread data off the stack */
|
||||
#if defined (MD_STACK_GROWS_DOWN)
|
||||
sp = stack->stk_top;
|
||||
#ifdef __ia64__
|
||||
/*
|
||||
* The stack segment is split in the middle. The upper half is used
|
||||
* as backing store for the register stack which grows upward.
|
||||
* The lower half is used for the traditional memory stack which
|
||||
* grows downward. Both stacks start in the middle and grow outward
|
||||
* from each other.
|
||||
*/
|
||||
sp -= (stk_size >> 1);
|
||||
bsp = sp;
|
||||
/* Make register stack 64-byte aligned */
|
||||
if ((unsigned long)bsp & 0x3f)
|
||||
bsp = bsp + (0x40 - ((unsigned long)bsp & 0x3f));
|
||||
stack->bsp = bsp + _ST_STACK_PAD_SIZE;
|
||||
#endif
|
||||
sp = sp - (ST_KEYS_MAX * sizeof(void *));
|
||||
ptds = (void **) sp;
|
||||
sp = sp - sizeof(_st_thread_t);
|
||||
thread = (_st_thread_t *) sp;
|
||||
|
||||
/* Make stack 64-byte aligned */
|
||||
if ((unsigned long)sp & 0x3f)
|
||||
sp = sp - ((unsigned long)sp & 0x3f);
|
||||
stack->sp = sp - _ST_STACK_PAD_SIZE;
|
||||
#elif defined (MD_STACK_GROWS_UP)
|
||||
sp = stack->stk_bottom;
|
||||
thread = (_st_thread_t *) sp;
|
||||
sp = sp + sizeof(_st_thread_t);
|
||||
ptds = (void **) sp;
|
||||
sp = sp + (ST_KEYS_MAX * sizeof(void *));
|
||||
|
||||
/* Make stack 64-byte aligned */
|
||||
if ((unsigned long)sp & 0x3f)
|
||||
sp = sp + (0x40 - ((unsigned long)sp & 0x3f));
|
||||
stack->sp = sp + _ST_STACK_PAD_SIZE;
|
||||
#else
|
||||
#error Unknown OS
|
||||
#endif
|
||||
|
||||
memset(thread, 0, sizeof(_st_thread_t));
|
||||
memset(ptds, 0, ST_KEYS_MAX * sizeof(void *));
|
||||
|
||||
/* Initialize thread */
|
||||
thread->private_data = ptds;
|
||||
thread->stack = stack;
|
||||
thread->start = start;
|
||||
thread->arg = arg;
|
||||
|
||||
#ifndef __ia64__
|
||||
/* Merge from https://github.com/michaeltalyansky/state-threads/commit/cce736426c2320ffec7c9820df49ee7a18ae638c */
|
||||
#if defined(__arm__) && !defined(MD_USE_BUILTIN_SETJMP) && __GLIBC_MINOR__ >= 19
|
||||
volatile void * lsp = PTR_MANGLE(stack->sp);
|
||||
if (_setjmp ((thread)->context))
|
||||
_st_thread_main();
|
||||
(thread)->context[0].__jmpbuf[8] = (long) (lsp);
|
||||
#else
|
||||
_ST_INIT_CONTEXT(thread, stack->sp, _st_thread_main);
|
||||
#endif
|
||||
#else
|
||||
_ST_INIT_CONTEXT(thread, stack->sp, stack->bsp, _st_thread_main);
|
||||
#endif
|
||||
|
||||
/* If thread is joinable, allocate a termination condition variable */
|
||||
if (joinable) {
|
||||
thread->term = st_cond_new();
|
||||
if (thread->term == NULL) {
|
||||
_st_stack_free(thread->stack);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make thread runnable */
|
||||
thread->state = _ST_ST_RUNNABLE;
|
||||
_st_active_count++;
|
||||
_ST_ADD_RUNQ(thread);
|
||||
#ifdef DEBUG
|
||||
_ST_ADD_THREADQ(thread);
|
||||
#endif
|
||||
|
||||
/* merge from https://github.com/toffaletti/state-threads/commit/7f57fc9acc05e657bca1223f1e5b9b1a45ed929b */
|
||||
#ifndef NVALGRIND
|
||||
if (!(thread->flags & _ST_FL_PRIMORDIAL)) {
|
||||
thread->stack->valgrind_stack_id = VALGRIND_STACK_REGISTER(thread->stack->stk_top, thread->stack->stk_bottom);
|
||||
}
|
||||
#endif
|
||||
|
||||
return thread;
|
||||
}
|
||||
|
||||
|
||||
_st_thread_t *st_thread_self(void)
|
||||
{
|
||||
return _ST_CURRENT_THREAD();
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
/* ARGSUSED */
|
||||
void _st_show_thread_stack(_st_thread_t *thread, const char *messg)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/* To be set from debugger */
|
||||
int _st_iterate_threads_flag = 0;
|
||||
|
||||
void _st_iterate_threads(void)
|
||||
{
|
||||
static _st_thread_t *thread = NULL;
|
||||
static jmp_buf orig_jb, save_jb;
|
||||
_st_clist_t *q;
|
||||
|
||||
if (!_st_iterate_threads_flag) {
|
||||
if (thread) {
|
||||
memcpy(thread->context, save_jb, sizeof(jmp_buf));
|
||||
MD_LONGJMP(orig_jb, 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (thread) {
|
||||
memcpy(thread->context, save_jb, sizeof(jmp_buf));
|
||||
_st_show_thread_stack(thread, NULL);
|
||||
} else {
|
||||
if (MD_SETJMP(orig_jb)) {
|
||||
_st_iterate_threads_flag = 0;
|
||||
thread = NULL;
|
||||
_st_show_thread_stack(thread, "Iteration completed");
|
||||
return;
|
||||
}
|
||||
thread = _ST_CURRENT_THREAD();
|
||||
_st_show_thread_stack(thread, "Iteration started");
|
||||
}
|
||||
|
||||
q = thread->tlink.next;
|
||||
if (q == &_ST_THREADQ)
|
||||
q = q->next;
|
||||
ST_ASSERT(q != &_ST_THREADQ);
|
||||
thread = _ST_THREAD_THREADQ_PTR(q);
|
||||
if (thread == _ST_CURRENT_THREAD())
|
||||
MD_LONGJMP(orig_jb, 1);
|
||||
memcpy(save_jb, thread->context, sizeof(jmp_buf));
|
||||
MD_LONGJMP(thread->context, 1);
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
10
trunk/3rdparty/st-srs/st.pc.in
vendored
Normal file
10
trunk/3rdparty/st-srs/st.pc.in
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
prefix=@prefix@
|
||||
exec_prefix=${prefix}
|
||||
libdir=${exec_prefix}/lib
|
||||
includedir=${prefix}/include
|
||||
|
||||
Name: libst
|
||||
Description: State Thread Library
|
||||
Version: @VERSION@
|
||||
Libs: -L${libdir} -lst
|
||||
Cflags: -I${includedir}
|
79
trunk/3rdparty/st-srs/st.spec
vendored
Normal file
79
trunk/3rdparty/st-srs/st.spec
vendored
Normal file
|
@ -0,0 +1,79 @@
|
|||
Summary: State Threads Library
|
||||
Name: st
|
||||
Version: 1.9
|
||||
Release: 1
|
||||
Copyright: MPL 1.2 or GPL 2+
|
||||
Packager: Wesley W. Terpstra <wesley@terpstra.ca>
|
||||
Source: http://prdownloads.sourceforge.net/state-threads/st-%{version}.tar.gz
|
||||
Prefix: /usr
|
||||
BuildRoot: /tmp/%{name}-%{version}-build
|
||||
Group: Development/Libraries
|
||||
|
||||
%description
|
||||
The State Threads library has an interface similar to POSIX threads.
|
||||
|
||||
However, the threads are actually all run in-process. This type of
|
||||
threading allows for controlled schedualing points. It is highly useful
|
||||
for designing robust and extremely scalable internet applications since
|
||||
there is no resource contention and locking is generally unnecessary.
|
||||
|
||||
It can be combined with traditional threading or multiple process
|
||||
parallelism to take advantage of multiple processors.
|
||||
|
||||
See: <http://state-threads.sourceforge.net/docs/st.html> for further
|
||||
information about how state threads improve performance.
|
||||
|
||||
%package -n libst-devel
|
||||
Summary: State Threads Library - Development Files
|
||||
Group: Development/Libraries
|
||||
Requires: libst1
|
||||
|
||||
%description -n libst-devel
|
||||
Development headers and documentation for libst
|
||||
|
||||
%package -n libst1
|
||||
Summary: State Threads Library - Shared Libs Major 1
|
||||
Group: System/Libraries
|
||||
|
||||
%description -n libst1
|
||||
Shared libraries for running applications linked against api version 1.
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
|
||||
%build
|
||||
make CONFIG_GUESS_PATH=/usr/share/automake default-optimized
|
||||
|
||||
%install
|
||||
if [ -d ${RPM_BUILD_ROOT} ]; then rm -rf ${RPM_BUILD_ROOT}; fi
|
||||
|
||||
mkdir -m 0755 -p ${RPM_BUILD_ROOT}/%{prefix}/lib/pkgconfig
|
||||
mkdir -m 0755 -p ${RPM_BUILD_ROOT}/%{prefix}/include
|
||||
mkdir -m 0755 -p ${RPM_BUILD_ROOT}/%{prefix}/share/doc/libst-devel
|
||||
cp -a obj/libst.* ${RPM_BUILD_ROOT}/%{prefix}/lib
|
||||
cp -a obj/st.h ${RPM_BUILD_ROOT}/%{prefix}/include
|
||||
sed "s*@prefix@*%{prefix}*g" <st.pc >${RPM_BUILD_ROOT}/%{prefix}/lib/pkgconfig/st.pc
|
||||
cp -a docs/* ${RPM_BUILD_ROOT}/%{prefix}/share/doc/libst-devel/
|
||||
cp -a examples ${RPM_BUILD_ROOT}/%{prefix}/share/doc/libst-devel/
|
||||
|
||||
%post -n libst1
|
||||
/sbin/ldconfig %{prefix}/lib
|
||||
|
||||
%files -n libst1
|
||||
%defattr(-,root,root)
|
||||
%{prefix}/lib/lib*.so.*
|
||||
|
||||
%files -n libst-devel
|
||||
%defattr(-,root,root)
|
||||
%{prefix}/include/*
|
||||
%{prefix}/lib/lib*.a
|
||||
%{prefix}/lib/lib*.so
|
||||
%{prefix}/lib/pkgconfig/st.pc
|
||||
%{prefix}/share/doc/libst-devel/*
|
||||
|
||||
%clean
|
||||
if [ -d ${RPM_BUILD_ROOT} ]; then rm -rf ${RPM_BUILD_ROOT}; fi
|
||||
|
||||
%changelog
|
||||
* Wed Dec 26 2001 Wesley W. Terpstra <wesley@terpstra.ca>
|
||||
- first rpms for libst-1.3.tar.gz
|
173
trunk/3rdparty/st-srs/stk.c
vendored
Normal file
173
trunk/3rdparty/st-srs/stk.c
vendored
Normal file
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape Portable Runtime library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Silicon Graphics, Inc.
|
||||
*
|
||||
* Portions created by SGI are Copyright (C) 2000-2001 Silicon
|
||||
* Graphics, Inc. All Rights Reserved.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is derived directly from Netscape Communications Corporation,
|
||||
* and consists of extensive modifications made during the year(s) 1999-2000.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include "common.h"
|
||||
|
||||
|
||||
/* How much space to leave between the stacks, at each end */
|
||||
#define REDZONE _ST_PAGE_SIZE
|
||||
|
||||
_st_clist_t _st_free_stacks = ST_INIT_STATIC_CLIST(&_st_free_stacks);
|
||||
int _st_num_free_stacks = 0;
|
||||
int _st_randomize_stacks = 0;
|
||||
|
||||
static char *_st_new_stk_segment(int size);
|
||||
|
||||
_st_stack_t *_st_stack_new(int stack_size)
|
||||
{
|
||||
_st_clist_t *qp;
|
||||
_st_stack_t *ts;
|
||||
int extra;
|
||||
|
||||
for (qp = _st_free_stacks.next; qp != &_st_free_stacks; qp = qp->next) {
|
||||
ts = _ST_THREAD_STACK_PTR(qp);
|
||||
if (ts->stk_size >= stack_size) {
|
||||
/* Found a stack that is big enough */
|
||||
ST_REMOVE_LINK(&ts->links);
|
||||
_st_num_free_stacks--;
|
||||
ts->links.next = NULL;
|
||||
ts->links.prev = NULL;
|
||||
return ts;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make a new thread stack object. */
|
||||
if ((ts = (_st_stack_t *)calloc(1, sizeof(_st_stack_t))) == NULL)
|
||||
return NULL;
|
||||
extra = _st_randomize_stacks ? _ST_PAGE_SIZE : 0;
|
||||
ts->vaddr_size = stack_size + 2*REDZONE + extra;
|
||||
ts->vaddr = _st_new_stk_segment(ts->vaddr_size);
|
||||
if (!ts->vaddr) {
|
||||
free(ts);
|
||||
return NULL;
|
||||
}
|
||||
ts->stk_size = stack_size;
|
||||
ts->stk_bottom = ts->vaddr + REDZONE;
|
||||
ts->stk_top = ts->stk_bottom + stack_size;
|
||||
|
||||
#ifdef DEBUG
|
||||
mprotect(ts->vaddr, REDZONE, PROT_NONE);
|
||||
mprotect(ts->stk_top + extra, REDZONE, PROT_NONE);
|
||||
#endif
|
||||
|
||||
if (extra) {
|
||||
long offset = (random() % extra) & ~0xf;
|
||||
|
||||
ts->stk_bottom += offset;
|
||||
ts->stk_top += offset;
|
||||
}
|
||||
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Free the stack for the current thread
|
||||
*/
|
||||
void _st_stack_free(_st_stack_t *ts)
|
||||
{
|
||||
if (!ts)
|
||||
return;
|
||||
|
||||
/* Put the stack on the free list */
|
||||
ST_APPEND_LINK(&ts->links, _st_free_stacks.prev);
|
||||
_st_num_free_stacks++;
|
||||
}
|
||||
|
||||
|
||||
static char *_st_new_stk_segment(int size)
|
||||
{
|
||||
#ifdef MALLOC_STACK
|
||||
void *vaddr = malloc(size);
|
||||
#else
|
||||
static int zero_fd = -1;
|
||||
int mmap_flags = MAP_PRIVATE;
|
||||
void *vaddr;
|
||||
|
||||
#if defined (MD_USE_SYSV_ANON_MMAP)
|
||||
if (zero_fd < 0) {
|
||||
if ((zero_fd = open("/dev/zero", O_RDWR, 0)) < 0)
|
||||
return NULL;
|
||||
fcntl(zero_fd, F_SETFD, FD_CLOEXEC);
|
||||
}
|
||||
#elif defined (MD_USE_BSD_ANON_MMAP)
|
||||
mmap_flags |= MAP_ANON;
|
||||
#else
|
||||
#error Unknown OS
|
||||
#endif
|
||||
|
||||
vaddr = mmap(NULL, size, PROT_READ | PROT_WRITE, mmap_flags, zero_fd, 0);
|
||||
if (vaddr == (void *)MAP_FAILED)
|
||||
return NULL;
|
||||
|
||||
#endif /* MALLOC_STACK */
|
||||
|
||||
return (char *)vaddr;
|
||||
}
|
||||
|
||||
|
||||
/* Not used */
|
||||
#if 0
|
||||
void _st_delete_stk_segment(char *vaddr, int size)
|
||||
{
|
||||
#ifdef MALLOC_STACK
|
||||
free(vaddr);
|
||||
#else
|
||||
(void) munmap(vaddr, size);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
int st_randomize_stacks(int on)
|
||||
{
|
||||
int wason = _st_randomize_stacks;
|
||||
|
||||
_st_randomize_stacks = on;
|
||||
if (on)
|
||||
srandom((unsigned int) st_utime());
|
||||
|
||||
return wason;
|
||||
}
|
368
trunk/3rdparty/st-srs/sync.c
vendored
Normal file
368
trunk/3rdparty/st-srs/sync.c
vendored
Normal file
|
@ -0,0 +1,368 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape Portable Runtime library.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s): Silicon Graphics, Inc.
|
||||
*
|
||||
* Portions created by SGI are Copyright (C) 2000-2001 Silicon
|
||||
* Graphics, Inc. All Rights Reserved.
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is derived directly from Netscape Communications Corporation,
|
||||
* and consists of extensive modifications made during the year(s) 1999-2000.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include "common.h"
|
||||
|
||||
|
||||
extern time_t _st_curr_time;
|
||||
extern st_utime_t _st_last_tset;
|
||||
extern int _st_active_count;
|
||||
|
||||
static st_utime_t (*_st_utime)(void) = NULL;
|
||||
|
||||
|
||||
/*****************************************
|
||||
* Time functions
|
||||
*/
|
||||
|
||||
st_utime_t st_utime(void)
|
||||
{
|
||||
if (_st_utime == NULL) {
|
||||
#ifdef MD_GET_UTIME
|
||||
MD_GET_UTIME();
|
||||
#else
|
||||
#error Unknown OS
|
||||
#endif
|
||||
}
|
||||
|
||||
return (*_st_utime)();
|
||||
}
|
||||
|
||||
|
||||
int st_set_utime_function(st_utime_t (*func)(void))
|
||||
{
|
||||
if (_st_active_count) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
_st_utime = func;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
st_utime_t st_utime_last_clock(void)
|
||||
{
|
||||
return _ST_LAST_CLOCK;
|
||||
}
|
||||
|
||||
|
||||
int st_timecache_set(int on)
|
||||
{
|
||||
int wason = (_st_curr_time) ? 1 : 0;
|
||||
|
||||
if (on) {
|
||||
_st_curr_time = time(NULL);
|
||||
_st_last_tset = st_utime();
|
||||
} else
|
||||
_st_curr_time = 0;
|
||||
|
||||
return wason;
|
||||
}
|
||||
|
||||
|
||||
time_t st_time(void)
|
||||
{
|
||||
if (_st_curr_time)
|
||||
return _st_curr_time;
|
||||
|
||||
return time(NULL);
|
||||
}
|
||||
|
||||
|
||||
int st_usleep(st_utime_t usecs)
|
||||
{
|
||||
_st_thread_t *me = _ST_CURRENT_THREAD();
|
||||
|
||||
if (me->flags & _ST_FL_INTERRUPT) {
|
||||
me->flags &= ~_ST_FL_INTERRUPT;
|
||||
errno = EINTR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (usecs != ST_UTIME_NO_TIMEOUT) {
|
||||
me->state = _ST_ST_SLEEPING;
|
||||
_ST_ADD_SLEEPQ(me, usecs);
|
||||
} else
|
||||
me->state = _ST_ST_SUSPENDED;
|
||||
|
||||
_ST_SWITCH_CONTEXT(me);
|
||||
|
||||
if (me->flags & _ST_FL_INTERRUPT) {
|
||||
me->flags &= ~_ST_FL_INTERRUPT;
|
||||
errno = EINTR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int st_sleep(int secs)
|
||||
{
|
||||
return st_usleep((secs >= 0) ? secs * (st_utime_t) 1000000LL : ST_UTIME_NO_TIMEOUT);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************
|
||||
* Condition variable functions
|
||||
*/
|
||||
|
||||
_st_cond_t *st_cond_new(void)
|
||||
{
|
||||
_st_cond_t *cvar;
|
||||
|
||||
cvar = (_st_cond_t *) calloc(1, sizeof(_st_cond_t));
|
||||
if (cvar) {
|
||||
ST_INIT_CLIST(&cvar->wait_q);
|
||||
}
|
||||
|
||||
return cvar;
|
||||
}
|
||||
|
||||
|
||||
int st_cond_destroy(_st_cond_t *cvar)
|
||||
{
|
||||
if (cvar->wait_q.next != &cvar->wait_q) {
|
||||
errno = EBUSY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(cvar);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int st_cond_timedwait(_st_cond_t *cvar, st_utime_t timeout)
|
||||
{
|
||||
_st_thread_t *me = _ST_CURRENT_THREAD();
|
||||
int rv;
|
||||
|
||||
if (me->flags & _ST_FL_INTERRUPT) {
|
||||
me->flags &= ~_ST_FL_INTERRUPT;
|
||||
errno = EINTR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Put caller thread on the condition variable's wait queue */
|
||||
me->state = _ST_ST_COND_WAIT;
|
||||
ST_APPEND_LINK(&me->wait_links, &cvar->wait_q);
|
||||
|
||||
if (timeout != ST_UTIME_NO_TIMEOUT)
|
||||
_ST_ADD_SLEEPQ(me, timeout);
|
||||
|
||||
_ST_SWITCH_CONTEXT(me);
|
||||
|
||||
ST_REMOVE_LINK(&me->wait_links);
|
||||
rv = 0;
|
||||
|
||||
if (me->flags & _ST_FL_TIMEDOUT) {
|
||||
me->flags &= ~_ST_FL_TIMEDOUT;
|
||||
errno = ETIME;
|
||||
rv = -1;
|
||||
}
|
||||
if (me->flags & _ST_FL_INTERRUPT) {
|
||||
me->flags &= ~_ST_FL_INTERRUPT;
|
||||
errno = EINTR;
|
||||
rv = -1;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
int st_cond_wait(_st_cond_t *cvar)
|
||||
{
|
||||
return st_cond_timedwait(cvar, ST_UTIME_NO_TIMEOUT);
|
||||
}
|
||||
|
||||
|
||||
static int _st_cond_signal(_st_cond_t *cvar, int broadcast)
|
||||
{
|
||||
_st_thread_t *thread;
|
||||
_st_clist_t *q;
|
||||
|
||||
for (q = cvar->wait_q.next; q != &cvar->wait_q; q = q->next) {
|
||||
thread = _ST_THREAD_WAITQ_PTR(q);
|
||||
if (thread->state == _ST_ST_COND_WAIT) {
|
||||
if (thread->flags & _ST_FL_ON_SLEEPQ)
|
||||
_ST_DEL_SLEEPQ(thread);
|
||||
|
||||
/* Make thread runnable */
|
||||
thread->state = _ST_ST_RUNNABLE;
|
||||
_ST_ADD_RUNQ(thread);
|
||||
if (!broadcast)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int st_cond_signal(_st_cond_t *cvar)
|
||||
{
|
||||
return _st_cond_signal(cvar, 0);
|
||||
}
|
||||
|
||||
|
||||
int st_cond_broadcast(_st_cond_t *cvar)
|
||||
{
|
||||
return _st_cond_signal(cvar, 1);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************
|
||||
* Mutex functions
|
||||
*/
|
||||
|
||||
_st_mutex_t *st_mutex_new(void)
|
||||
{
|
||||
_st_mutex_t *lock;
|
||||
|
||||
lock = (_st_mutex_t *) calloc(1, sizeof(_st_mutex_t));
|
||||
if (lock) {
|
||||
ST_INIT_CLIST(&lock->wait_q);
|
||||
lock->owner = NULL;
|
||||
}
|
||||
|
||||
return lock;
|
||||
}
|
||||
|
||||
|
||||
int st_mutex_destroy(_st_mutex_t *lock)
|
||||
{
|
||||
if (lock->owner != NULL || lock->wait_q.next != &lock->wait_q) {
|
||||
errno = EBUSY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int st_mutex_lock(_st_mutex_t *lock)
|
||||
{
|
||||
_st_thread_t *me = _ST_CURRENT_THREAD();
|
||||
|
||||
if (me->flags & _ST_FL_INTERRUPT) {
|
||||
me->flags &= ~_ST_FL_INTERRUPT;
|
||||
errno = EINTR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lock->owner == NULL) {
|
||||
/* Got the mutex */
|
||||
lock->owner = me;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lock->owner == me) {
|
||||
errno = EDEADLK;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Put caller thread on the mutex's wait queue */
|
||||
me->state = _ST_ST_LOCK_WAIT;
|
||||
ST_APPEND_LINK(&me->wait_links, &lock->wait_q);
|
||||
|
||||
_ST_SWITCH_CONTEXT(me);
|
||||
|
||||
ST_REMOVE_LINK(&me->wait_links);
|
||||
|
||||
if ((me->flags & _ST_FL_INTERRUPT) && lock->owner != me) {
|
||||
me->flags &= ~_ST_FL_INTERRUPT;
|
||||
errno = EINTR;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int st_mutex_unlock(_st_mutex_t *lock)
|
||||
{
|
||||
_st_thread_t *thread;
|
||||
_st_clist_t *q;
|
||||
|
||||
if (lock->owner != _ST_CURRENT_THREAD()) {
|
||||
errno = EPERM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (q = lock->wait_q.next; q != &lock->wait_q; q = q->next) {
|
||||
thread = _ST_THREAD_WAITQ_PTR(q);
|
||||
if (thread->state == _ST_ST_LOCK_WAIT) {
|
||||
lock->owner = thread;
|
||||
/* Make thread runnable */
|
||||
thread->state = _ST_ST_RUNNABLE;
|
||||
_ST_ADD_RUNQ(thread);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* No threads waiting on this mutex */
|
||||
lock->owner = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int st_mutex_trylock(_st_mutex_t *lock)
|
||||
{
|
||||
if (lock->owner != NULL) {
|
||||
errno = EBUSY;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Got the mutex */
|
||||
lock->owner = _ST_CURRENT_THREAD();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
BIN
trunk/3rdparty/state-threads-1.9.1.tar.gz
vendored
BIN
trunk/3rdparty/state-threads-1.9.1.tar.gz
vendored
Binary file not shown.
BIN
trunk/3rdparty/x264-snapshot-20181116-2245.zip
vendored
BIN
trunk/3rdparty/x264-snapshot-20181116-2245.zip
vendored
Binary file not shown.
BIN
trunk/3rdparty/yasm-1.2.0.zip
vendored
BIN
trunk/3rdparty/yasm-1.2.0.zip
vendored
Binary file not shown.
|
@ -23,6 +23,8 @@ echo "# build ${APP_TARGET}" >> ${FILE}
|
|||
# generate the binary depends, for example:
|
||||
# srs: objs/srs
|
||||
echo "${BUILD_KEY}: ${APP_TARGET}" >> ${FILE}
|
||||
echo "" >> ${FILE}
|
||||
|
||||
# the link commands, for example:
|
||||
# objs/srs: objs/src/core/srs_core.o
|
||||
echo -n "${APP_TARGET}: " >> ${FILE}
|
||||
|
@ -88,5 +90,6 @@ done
|
|||
# link options.
|
||||
echo -n "${LINK_OPTIONS}" >> ${FILE}
|
||||
echo "" >> ${FILE}
|
||||
echo "" >> ${FILE}
|
||||
|
||||
echo -n "Generate app ${APP_NAME} ok"; echo '!';
|
||||
|
|
|
@ -40,18 +40,9 @@ function srs_undefine_macro()
|
|||
}
|
||||
|
||||
# export the preset.
|
||||
if [ $SRS_OSX = YES ]; then
|
||||
srs_define_macro "SRS_OSX" $SRS_AUTO_HEADERS_H
|
||||
fi
|
||||
if [ $SRS_X86_X64 = YES ]; then
|
||||
srs_define_macro "SRS_X86_X64" $SRS_AUTO_HEADERS_H
|
||||
fi
|
||||
if [ $SRS_ARM_UBUNTU12 = YES ]; then
|
||||
srs_define_macro "SRS_ARM_UBUNTU12" $SRS_AUTO_HEADERS_H
|
||||
fi
|
||||
if [ $SRS_MIPS_UBUNTU12 = YES ]; then
|
||||
srs_define_macro "SRS_MIPS_UBUNTU12" $SRS_AUTO_HEADERS_H
|
||||
fi
|
||||
if [ $SRS_PI = YES ]; then
|
||||
srs_define_macro "SRS_PI" $SRS_AUTO_HEADERS_H
|
||||
fi
|
||||
|
@ -69,28 +60,7 @@ echo "" >> $SRS_AUTO_HEADERS_H
|
|||
#####################################################################################
|
||||
# generate auto headers file, depends on the finished of options.sh
|
||||
#####################################################################################
|
||||
# write to source file
|
||||
if [ $SRS_CROSS_BUILD = YES ]; then
|
||||
__TOOL_CHAIN="cc=$SrsArmCC gcc=$SrsArmGCC g++=$SrsArmCXX ar=$SrsArmAR ld=$SrsArmLD randlib=$SrsArmRANDLIB" && echo "$__TOOL_CHAIN"
|
||||
srs_define_macro_value "SRS_AUTO_EMBEDED_TOOL_CHAIN" "\"$__TOOL_CHAIN\"" $SRS_AUTO_HEADERS_H
|
||||
else
|
||||
srs_undefine_macro "SRS_AUTO_EMBEDED_TOOL_CHAIN" $SRS_AUTO_HEADERS_H
|
||||
fi
|
||||
echo "" >> $SRS_AUTO_HEADERS_H
|
||||
|
||||
# auto headers in depends.
|
||||
if [ $SRS_KAFKA = YES ]; then
|
||||
srs_define_macro "SRS_AUTO_KAFKA" $SRS_AUTO_HEADERS_H
|
||||
else
|
||||
srs_undefine_macro "SRS_AUTO_KAFKA" $SRS_AUTO_HEADERS_H
|
||||
fi
|
||||
|
||||
if [ $SRS_NGINX = YES ]; then
|
||||
srs_define_macro "SRS_AUTO_NGINX" $SRS_AUTO_HEADERS_H
|
||||
else
|
||||
srs_undefine_macro "SRS_AUTO_NGINX" $SRS_AUTO_HEADERS_H
|
||||
fi
|
||||
|
||||
if [ $SRS_HDS = YES ]; then
|
||||
srs_define_macro "SRS_AUTO_HDS" $SRS_AUTO_HEADERS_H
|
||||
else
|
||||
|
@ -109,13 +79,6 @@ else
|
|||
srs_undefine_macro "SRS_AUTO_UTEST" $SRS_AUTO_HEADERS_H
|
||||
fi
|
||||
|
||||
# whether compile ffmpeg tool
|
||||
if [ $SRS_FFMPEG_TOOL = YES ]; then
|
||||
srs_define_macro "SRS_AUTO_FFMPEG_TOOL" $SRS_AUTO_HEADERS_H
|
||||
else
|
||||
srs_undefine_macro "SRS_AUTO_FFMPEG_TOOL" $SRS_AUTO_HEADERS_H
|
||||
fi
|
||||
|
||||
# whatever the FFMPEG tools, if transcode and ingest specified,
|
||||
# srs always compile the FFMPEG tool stub which used to start the FFMPEG process.
|
||||
if [ $SRS_FFMPEG_STUB = YES ]; then
|
||||
|
@ -153,27 +116,6 @@ fi
|
|||
#####################################################################################
|
||||
# for embeded.
|
||||
#####################################################################################
|
||||
if [ $SRS_CROSS_BUILD = YES ]; then
|
||||
srs_define_macro "SRS_AUTO_EMBEDED_CPU" $SRS_AUTO_HEADERS_H
|
||||
else
|
||||
srs_undefine_macro "SRS_AUTO_EMBEDED_CPU" $SRS_AUTO_HEADERS_H
|
||||
fi
|
||||
|
||||
# arm
|
||||
if [ $SRS_ARM_UBUNTU12 = YES ]; then
|
||||
srs_define_macro "SRS_AUTO_ARM_UBUNTU12" $SRS_AUTO_HEADERS_H
|
||||
else
|
||||
srs_undefine_macro "SRS_AUTO_ARM_UBUNTU12" $SRS_AUTO_HEADERS_H
|
||||
fi
|
||||
|
||||
# mips
|
||||
if [ $SRS_MIPS_UBUNTU12 = YES ]; then
|
||||
srs_define_macro "SRS_AUTO_MIPS_UBUNTU12" $SRS_AUTO_HEADERS_H
|
||||
else
|
||||
srs_undefine_macro "SRS_AUTO_MIPS_UBUNTU12" $SRS_AUTO_HEADERS_H
|
||||
fi
|
||||
|
||||
echo "" >> $SRS_AUTO_HEADERS_H
|
||||
# for log level compile settings
|
||||
if [ $SRS_LOG_VERBOSE = YES ]; then
|
||||
srs_define_macro "SRS_AUTO_VERBOSE" $SRS_AUTO_HEADERS_H
|
||||
|
@ -190,6 +132,11 @@ if [ $SRS_LOG_TRACE = YES ]; then
|
|||
else
|
||||
srs_undefine_macro "SRS_AUTO_TRACE" $SRS_AUTO_HEADERS_H
|
||||
fi
|
||||
if [ $SRS_CROSS_BUILD = YES ]; then
|
||||
srs_define_macro "SRS_AUTO_CROSSBUILD" $SRS_AUTO_HEADERS_H
|
||||
else
|
||||
srs_undefine_macro "SRS_AUTO_CROSSBUILD" $SRS_AUTO_HEADERS_H
|
||||
fi
|
||||
|
||||
# prefix
|
||||
echo "" >> $SRS_AUTO_HEADERS_H
|
||||
|
@ -200,12 +147,16 @@ echo "" >> $SRS_AUTO_HEADERS_H
|
|||
#####################################################################################
|
||||
# generated the contributors from AUTHORS.txt
|
||||
#####################################################################################
|
||||
SRS_CONSTRIBUTORS=`cat ../AUTHORS.txt|grep "*"|awk '{print $2}'`
|
||||
echo "#define SRS_AUTO_CONSTRIBUTORS \"\\" >> $SRS_AUTO_HEADERS_H
|
||||
for CONTRIBUTOR in $SRS_CONSTRIBUTORS; do
|
||||
echo "${CONTRIBUTOR} \\" >> $SRS_AUTO_HEADERS_H
|
||||
done
|
||||
echo "\"" >> $SRS_AUTO_HEADERS_H
|
||||
if [[ -f ../AUTHORS.txt ]]; then
|
||||
SRS_CONSTRIBUTORS=`cat ../AUTHORS.txt|grep "*"|awk '{print $2}'`
|
||||
echo "#define SRS_AUTO_CONSTRIBUTORS \"\\" >> $SRS_AUTO_HEADERS_H
|
||||
for CONTRIBUTOR in $SRS_CONSTRIBUTORS; do
|
||||
echo "${CONTRIBUTOR} \\" >> $SRS_AUTO_HEADERS_H
|
||||
done
|
||||
echo "\"" >> $SRS_AUTO_HEADERS_H
|
||||
else
|
||||
echo "#define SRS_AUTO_CONSTRIBUTORS \"ossrs\"" >> $SRS_AUTO_HEADERS_H
|
||||
fi
|
||||
|
||||
# new empty line to auto headers file.
|
||||
echo "" >> $SRS_AUTO_HEADERS_H
|
||||
|
|
|
@ -76,7 +76,6 @@ else
|
|||
cd $ff_current_dir &&
|
||||
rm -rf x264-snapshot-20181116-2245 && unzip -q ${ff_src_dir}/x264-snapshot-20181116-2245.zip &&
|
||||
cd x264-snapshot-20181116-2245 &&
|
||||
# chmod +w configure && patch -p0 <../../../3rdparty/patches/5.x264.osx.gcc.patch &&
|
||||
./configure --prefix=${ff_release_dir} --disable-opencl --bit-depth=all \
|
||||
--enable-static --disable-avs --disable-swscale --disable-lavf \
|
||||
--disable-ffms --disable-gpac --disable-cli &&
|
||||
|
|
|
@ -1,25 +1,45 @@
|
|||
#!/bin/bash
|
||||
|
||||
# In .circleci/config.yml, generate *.gcno with
|
||||
# ./configure --gcov --without-research --without-librtmp
|
||||
# ./configure --gcov --without-research --without-librtmp && make
|
||||
# and generate *.gcda by
|
||||
# ./objs/srs_utest
|
||||
|
||||
# Workdir is objs/cover.
|
||||
workdir=`pwd`/objs/cover
|
||||
|
||||
# Tool git is required to map the right path.
|
||||
git --version >/dev/null 2>&1
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then echo "Tool git is required, ret=$ret"; exit $ret; fi
|
||||
|
||||
# Create trunk under workdir.
|
||||
mkdir -p $workdir && cd $workdir
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then echo "Enter workdir failed, ret=$ret"; exit $ret; fi
|
||||
|
||||
# Collect all *.gcno and *.gcda to objs/cover.
|
||||
(mkdir -p objs/cover && cd objs/cover &&
|
||||
cp -R ../../src . &&
|
||||
for file in `find ../src -name "*.gcno"`; do cp $file .; done &&
|
||||
for file in `find ../src -name "*.gcda"`; do cp $file .; done)
|
||||
cd $workdir && (rm -rf src && cp -R ../../src . && cp -R ../src .)
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then echo "Collect *.gcno and *.gcda failed, ret=$ret"; exit $ret; fi
|
||||
|
||||
# Generate *.gcov to objs/cover
|
||||
for file in `find src -name "*.cpp"`; do
|
||||
(mkdir -p objs/cover && cd objs/cover && gcov ../../$file -o .)
|
||||
# Generate *.gcov for coverage.
|
||||
cd $workdir &&
|
||||
for file in `find src -name "*.cpp"|grep -v utest`; do
|
||||
gcov $file -o `dirname $file`
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then echo "Collect $file failed, ret=$ret"; exit $ret; fi
|
||||
done
|
||||
|
||||
# Cook the gcov files.
|
||||
cd $workdir &&
|
||||
find . -name "*.gcov"|grep -v srs|xargs rm -f
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then echo "Cook gcov files failed, ret=$ret"; exit $ret; fi
|
||||
|
||||
# Upload report with *.gcov
|
||||
# Remark: The file codecov.yml is not neccessary. It literally depends on git.
|
||||
# Note: The right path is like:
|
||||
# https://codecov.io/gh/ossrs/srs/src/3.0release/trunk/src/protocol/srs_rtmp_stack.cpp
|
||||
# https://codecov.io/gh/ossrs/srs/src/20fbb4466fdc8ba5d810b8570df6004063212838/trunk/src/protocol/srs_rtmp_stack.cpp
|
||||
# Remark: It takes a few minutes to sync with github, so it might not available when CircleCI is done.
|
||||
# https://circleci.com/gh/ossrs/srs/tree/3.0release
|
||||
cd $workdir &&
|
||||
export CODECOV_TOKEN="493bba46-c468-4e73-8b45-8cdd8ff62d96" &&
|
||||
mkdir -p objs/cover && cd objs/cover &&
|
||||
bash <(curl -s https://codecov.io/bash)
|
||||
exit 0
|
||||
bash <(curl -s https://codecov.io/bash) &&
|
||||
echo "Done" && exit 0
|
||||
|
|
|
@ -45,24 +45,6 @@ function Ubuntu_prepare()
|
|||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# cross build for arm, install the cross build tool chain.
|
||||
if [ $SRS_ARM_UBUNTU12 = YES ]; then
|
||||
$SrsArmCC --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||
echo "Installing gcc-arm-linux-gnueabi g++-arm-linux-gnueabi."
|
||||
require_sudoer "sudo apt-get install -y --force-yes gcc-arm-linux-gnueabi g++-arm-linux-gnueabi"
|
||||
sudo apt-get install -y --force-yes gcc-arm-linux-gnueabi g++-arm-linux-gnueabi; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||
echo "The gcc-arm-linux-gnueabi g++-arm-linux-gnueabi are installed."
|
||||
fi
|
||||
fi
|
||||
|
||||
# cross build for mips, user must installed the tool chain.
|
||||
if [ $SRS_MIPS_UBUNTU12 = YES ]; then
|
||||
$SrsArmCC --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||
echo "You must install the tool chain: $SrsArmCC"
|
||||
return 2
|
||||
fi
|
||||
fi
|
||||
|
||||
OS_IS_UBUNTU=YES
|
||||
echo "Installing tools for Ubuntu."
|
||||
|
@ -114,43 +96,11 @@ function Ubuntu_prepare()
|
|||
if [[ $SRS_VALGRIND == YES ]]; then
|
||||
if [[ ! -f /usr/include/valgrind/valgrind.h ]]; then
|
||||
echo "Installing valgrind-dev."
|
||||
require_sudoer "sudo apt-get install -y --force-yes valgrind-dev"
|
||||
require_sudoer "sudo apt-get install -y --force-yes valgrind-dbg"
|
||||
sudo apt-get install -y --force-yes valgrind-dev; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||
echo "The valgrind-dev is installed."
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $SRS_NGINX = YES ]; then
|
||||
if [[ ! -f /usr/include/pcre.h ]]; then
|
||||
echo "Installing libpcre3-dev."
|
||||
require_sudoer "sudo apt-get install -y --force-yes libpcre3-dev"
|
||||
sudo apt-get install -y --force-yes libpcre3-dev; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||
echo "The libpcre3-dev is installed."
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $SRS_FFMPEG_TOOL = YES ]; then
|
||||
autoconf --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||
echo "Installing autoconf."
|
||||
require_sudoer "sudo apt-get install -y --force-yes autoconf"
|
||||
sudo apt-get install -y --force-yes autoconf; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||
echo "The autoconf is installed."
|
||||
fi
|
||||
|
||||
libtool --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||
echo "Installing libtool."
|
||||
require_sudoer "sudo apt-get install -y --force-yes libtool"
|
||||
sudo apt-get install -y --force-yes libtool; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||
echo "The libtool is installed."
|
||||
fi
|
||||
|
||||
if [[ ! -f /usr/include/zlib.h ]]; then
|
||||
echo "Installing zlib1g-dev."
|
||||
require_sudoer "sudo apt-get install -y --force-yes zlib1g-dev"
|
||||
sudo apt-get install -y --force-yes zlib1g-dev; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||
echo "The zlib1g-dev is installed."
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Tools for Ubuntu are installed."
|
||||
return 0
|
||||
|
@ -168,12 +118,6 @@ function Centos_prepare()
|
|||
if [[ ! -f /etc/redhat-release ]]; then
|
||||
return 0;
|
||||
fi
|
||||
|
||||
# cross build for arm, install the cross build tool chain.
|
||||
if [ $SRS_CROSS_BUILD = YES ]; then
|
||||
echo "CentOS doesn't support crossbuild for arm/mips, please use Ubuntu instead."
|
||||
return 1
|
||||
fi
|
||||
|
||||
OS_IS_CENTOS=YES
|
||||
echo "Installing tools for Centos."
|
||||
|
@ -230,45 +174,6 @@ function Centos_prepare()
|
|||
echo "The valgrind-devel is installed."
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $SRS_NGINX = YES ]; then
|
||||
if [[ ! -f /usr/include/pcre.h ]]; then
|
||||
echo "Installing pcre-devel."
|
||||
require_sudoer "sudo yum install -y pcre-devel"
|
||||
sudo yum install -y pcre-devel; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||
echo "The pcre-devel is installed."
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $SRS_FFMPEG_TOOL = YES ]; then
|
||||
automake --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||
echo "Installing automake."
|
||||
require_sudoer "sudo yum install -y automake"
|
||||
sudo yum install -y automake; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||
echo "The automake is installed."
|
||||
fi
|
||||
|
||||
autoconf --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||
echo "Installing autoconf."
|
||||
require_sudoer "sudo yum install -y autoconf"
|
||||
sudo yum install -y autoconf; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||
echo "The autoconf is installed."
|
||||
fi
|
||||
|
||||
libtool --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||
echo "Installing libtool."
|
||||
require_sudoer "sudo yum install -y libtool"
|
||||
sudo yum install -y libtool; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||
echo "The libtool is installed."
|
||||
fi
|
||||
|
||||
if [[ ! -f /usr/include/zlib.h ]]; then
|
||||
echo "Installing zlib-devel."
|
||||
require_sudoer "sudo yum install -y zlib-devel"
|
||||
sudo yum install -y zlib-devel; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||
echo "The zlib-devel is installed."
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Tools for Centos are installed."
|
||||
return 0
|
||||
|
@ -280,146 +185,11 @@ fi
|
|||
#####################################################################################
|
||||
# for Centos, auto install tools by yum
|
||||
#####################################################################################
|
||||
OS_IS_OSX=NO
|
||||
function OSX_prepare()
|
||||
{
|
||||
uname -s|grep Darwin >/dev/null 2>&1
|
||||
ret=$?; if [[ 0 -ne $ret ]]; then
|
||||
if [ $SRS_OSX = YES ]; then
|
||||
echo "Current OS `uname -s` is not OSX, please check your configure options."
|
||||
exit 1;
|
||||
fi
|
||||
return 0;
|
||||
fi
|
||||
|
||||
# cross build for arm, install the cross build tool chain.
|
||||
if [ $SRS_CROSS_BUILD = YES ]; then
|
||||
echo "OSX doesn't support crossbuild for arm/mips, please use Ubuntu instead."
|
||||
return 1
|
||||
fi
|
||||
|
||||
OS_IS_OSX=YES
|
||||
echo "Installing tools for OSX."
|
||||
# requires the osx when os
|
||||
if [ $OS_IS_OSX = YES ]; then
|
||||
if [ $SRS_OSX = NO ]; then
|
||||
echo "Invalid configure options for OSX, please specify --osx."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
brew --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||
echo "Installing brew."
|
||||
echo "ruby -e \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)\""
|
||||
ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||
echo "The brew is installed."
|
||||
fi
|
||||
|
||||
gcc --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||
echo "Installing gcc."
|
||||
echo "brew install gcc"
|
||||
brew install gcc; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||
echo "The gcc is installed."
|
||||
fi
|
||||
|
||||
g++ --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||
echo "Installing gcc-c++."
|
||||
echo "brew install gcc-c++"
|
||||
brew install gcc-c++; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||
echo "The gcc-c++ is installed."
|
||||
fi
|
||||
|
||||
make --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||
echo "Installing make."
|
||||
echo "brew install make"
|
||||
brew install make; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||
echo "The make is installed."
|
||||
fi
|
||||
|
||||
patch --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||
echo "Installing patch."
|
||||
echo "brew install patch"
|
||||
brew install patch; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||
echo "The patch is installed."
|
||||
fi
|
||||
|
||||
unzip --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||
echo "Installing unzip."
|
||||
echo "brew install unzip"
|
||||
brew install unzip; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||
echo "The unzip is installed."
|
||||
fi
|
||||
|
||||
if [[ $SRS_VALGRIND == YES ]]; then
|
||||
valgrind --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||
echo "Installing valgrind."
|
||||
echo "brew install valgrind"
|
||||
brew install valgrind; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||
echo "The valgrind is installed."
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $SRS_NGINX = YES ]; then
|
||||
if [[ ! -f /usr/local/include/pcre.h ]]; then
|
||||
echo "Installing pcre."
|
||||
echo "brew install pcre"
|
||||
brew install pcre; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||
echo "The pcre is installed."
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ $SRS_FFMPEG_TOOL = YES ]; then
|
||||
automake --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||
echo "Installing automake."
|
||||
echo "brew install automake"
|
||||
brew install automake; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||
echo "The automake is installed."
|
||||
fi
|
||||
|
||||
autoconf --help >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||
echo "Installing autoconf."
|
||||
echo "brew install autoconf"
|
||||
brew install autoconf; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||
echo "The autoconf is installed."
|
||||
fi
|
||||
|
||||
which libtool >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||
echo "Installing libtool."
|
||||
echo "brew install libtool"
|
||||
brew install libtool; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||
echo "The libtool is installed."
|
||||
fi
|
||||
|
||||
brew info zlib >/dev/null 2>&1; ret=$?; if [[ 0 -ne $ret ]]; then
|
||||
echo "Installing zlib."
|
||||
echo "brew install zlib"
|
||||
brew install zlib; ret=$?; if [[ 0 -ne $ret ]]; then return $ret; fi
|
||||
echo "The zlib is installed."
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "Tools for OSX are installed."
|
||||
return 0
|
||||
}
|
||||
# donot prepare tools, for srs-librtmp depends only gcc and g++.
|
||||
if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
||||
OSX_prepare; ret=$?; if [[ 0 -ne $ret ]]; then echo "Install tools for OSX failed, ret=$ret"; exit $ret; fi
|
||||
fi
|
||||
|
||||
# We must use a bash function instead of variable.
|
||||
function sed_utility() {
|
||||
if [ $OS_IS_OSX = YES ]; then
|
||||
sed -i '' "$@"
|
||||
else
|
||||
sed -i "$@"
|
||||
fi
|
||||
|
||||
sed -i "$@"
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then
|
||||
if [ $OS_IS_OSX = YES ]; then
|
||||
echo "sed -i '' \"$@\""
|
||||
else
|
||||
echo "sed -i \"$@\""
|
||||
fi
|
||||
echo "sed -i \"$@\""
|
||||
return $ret
|
||||
fi
|
||||
}
|
||||
|
@ -428,15 +198,15 @@ SED="sed_utility" && echo "SED is $SED"
|
|||
#####################################################################################
|
||||
# check the os.
|
||||
#####################################################################################
|
||||
# user must specifies something what a fuck, we suppport following os:
|
||||
# centos/ubuntu/osx,
|
||||
# Only supports:
|
||||
# linux, centos/ubuntu as such,
|
||||
# cross build for embeded system, for example, mips or arm,
|
||||
# directly build on arm/mips, for example, pi or cubie,
|
||||
# export srs-librtmp
|
||||
# others is invalid.
|
||||
if [[ $OS_IS_UBUNTU = NO && $OS_IS_CENTOS = NO && $OS_IS_OSX = NO && $SRS_EXPORT_LIBRTMP_PROJECT = NO ]]; then
|
||||
if [[ $OS_IS_UBUNTU = NO && $OS_IS_CENTOS = NO && $SRS_EXPORT_LIBRTMP_PROJECT = NO ]]; then
|
||||
if [[ $SRS_PI = NO && $SRS_CUBIE = NO && $SRS_CROSS_BUILD = NO ]]; then
|
||||
echo "What a fuck, your OS `uname -s` is not supported."
|
||||
echo "Your OS `uname -s` is not supported."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
@ -447,45 +217,25 @@ fi
|
|||
if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
||||
# check the cross build flag file, if flag changed, need to rebuild the st.
|
||||
_ST_MAKE=linux-debug && _ST_EXTRA_CFLAGS="-DMD_HAVE_EPOLL"
|
||||
# for osx, use darwin for st, donot use epoll.
|
||||
if [ $OS_IS_OSX = YES ]; then
|
||||
_ST_MAKE=darwin-debug && _ST_EXTRA_CFLAGS="-DMD_HAVE_KQUEUE -I/usr/local/include"
|
||||
fi
|
||||
if [[ $SRS_VALGRIND == YES ]]; then
|
||||
_ST_EXTRA_CFLAGS="$_ST_EXTRA_CFLAGS -DMD_VALGRIND"
|
||||
fi
|
||||
# Pass the global extra flags.
|
||||
if [[ $SRS_EXTRA_FLAGS != '' ]]; then
|
||||
_ST_EXTRA_CFLAGS="$_ST_EXTRA_CFLAGS $SRS_EXTRA_FLAGS"
|
||||
fi
|
||||
# Patched ST from https://github.com/ossrs/state-threads/tree/srs
|
||||
if [ $SRS_CROSS_BUILD = YES ]; then
|
||||
# ok, arm specified, if the flag filed does not exists, need to rebuild.
|
||||
if [[ -f ${SRS_OBJS}/_flag.st.cross.build.tmp && -f ${SRS_OBJS}/st/libst.a ]]; then
|
||||
echo "The state-threads for arm is ok.";
|
||||
else
|
||||
echo "Building state-threads for arm.";
|
||||
(
|
||||
rm -rf ${SRS_OBJS}/state-threads-1.9.1 && cd ${SRS_OBJS} &&
|
||||
tar xf ../3rdparty/state-threads-1.9.1.tar.gz && cd state-threads-1.9.1 && chmod +w * &&
|
||||
patch -p0 < ../../3rdparty/patches/6.st.osx10.14.build.patch &&
|
||||
make ${_ST_MAKE} CC=${SrsArmCC} AR=${SrsArmAR} LD=${SrsArmLD} RANDLIB=${SrsArmRANDLIB} EXTRA_CFLAGS="${_ST_EXTRA_CFLAGS}" &&
|
||||
cd .. && rm -f st && ln -sf state-threads-1.9.1/obj st &&
|
||||
rm -f state-threads && ln -sf state-threads-1.9.1 state-threads &&
|
||||
cd .. && touch ${SRS_OBJS}/_flag.st.cross.build.tmp
|
||||
)
|
||||
fi
|
||||
if [[ -f ${SRS_OBJS}/st/libst.a ]]; then
|
||||
echo "The state-threads is ok.";
|
||||
else
|
||||
if [[ ! -f ${SRS_OBJS}/_flag.st.cross.build.tmp && -f ${SRS_OBJS}/st/libst.a ]]; then
|
||||
echo "The state-threads is ok.";
|
||||
else
|
||||
echo "Building state-threads.";
|
||||
(
|
||||
rm -rf ${SRS_OBJS}/state-threads-1.9.1 && cd ${SRS_OBJS} &&
|
||||
tar xf ../3rdparty/state-threads-1.9.1.tar.gz && cd state-threads-1.9.1 && chmod +w * &&
|
||||
patch -p0 < ../../3rdparty/patches/6.st.osx10.14.build.patch &&
|
||||
make ${_ST_MAKE} EXTRA_CFLAGS="${_ST_EXTRA_CFLAGS}" &&
|
||||
cd .. && rm -f st && ln -sf state-threads-1.9.1/obj st &&
|
||||
rm -f state-threads && ln -sf state-threads-1.9.1 state-threads &&
|
||||
cd .. && rm -f ${SRS_OBJS}/_flag.st.cross.build.tmp
|
||||
)
|
||||
fi
|
||||
echo "Building state-threads.";
|
||||
(
|
||||
rm -rf ${SRS_OBJS}/st-srs && cd ${SRS_OBJS} &&
|
||||
ln -sf ../3rdparty/st-srs && cd st-srs &&
|
||||
make clean && make ${_ST_MAKE} EXTRA_CFLAGS="${_ST_EXTRA_CFLAGS}" \
|
||||
CC=${SRS_TOOL_CC} AR=${SRS_TOOL_AR} LD=${SRS_TOOL_LD} RANDLIB=${SRS_TOOL_RANDLIB} &&
|
||||
cd .. && rm -f st && ln -sf st-srs/obj st
|
||||
)
|
||||
fi
|
||||
# check status
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then echo "Build state-threads failed, ret=$ret"; exit $ret; fi
|
||||
|
@ -507,30 +257,6 @@ END
|
|||
if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
||||
mkdir -p ${SRS_OBJS}/nginx
|
||||
fi
|
||||
# make nginx
|
||||
__SRS_BUILD_NGINX=NO; if [ $SRS_CROSS_BUILD = NO ]; then if [ $SRS_NGINX = YES ]; then __SRS_BUILD_NGINX=YES; fi fi
|
||||
if [ $__SRS_BUILD_NGINX = YES ]; then
|
||||
if [[ -f ${SRS_OBJS}/nginx/sbin/nginx ]]; then
|
||||
echo "The nginx-1.5.7 is ok.";
|
||||
else
|
||||
echo "Building nginx-1.5.7";
|
||||
(
|
||||
rm -rf ${SRS_OBJS}/nginx-1.5.7 && cd ${SRS_OBJS} &&
|
||||
unzip -q ../3rdparty/nginx-1.5.7.zip && cd nginx-1.5.7 &&
|
||||
./configure --prefix=`pwd`/_release && make ${SRS_JOBS} && make install &&
|
||||
cd .. && rm -rf nginx && ln -sf nginx-1.5.7/_release nginx
|
||||
)
|
||||
fi
|
||||
# check status
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then echo "Build nginx-1.5.7 failed, ret=$ret"; exit $ret; fi
|
||||
if [ ! -f ${SRS_OBJS}/nginx/sbin/nginx ]; then echo "Build nginx-1.5.7 failed."; exit -1; fi
|
||||
|
||||
# use current user to config nginx,
|
||||
# srs will write ts/m3u8 file use current user,
|
||||
# nginx default use nobody, so cannot read the ts/m3u8 created by srs.
|
||||
cp ${SRS_OBJS}/nginx/conf/nginx.conf ${SRS_OBJS}/nginx/conf/nginx.conf.bk
|
||||
$SED "s/^.user nobody;/user `whoami`;/g" ${SRS_OBJS}/nginx/conf/nginx.conf
|
||||
fi
|
||||
|
||||
# the demo dir.
|
||||
if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
||||
|
@ -594,94 +320,55 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
|||
fi
|
||||
|
||||
#####################################################################################
|
||||
# generate demo index.html
|
||||
# openssl, for rtmp complex handshake and HLS encryption.
|
||||
#####################################################################################
|
||||
# if nginx enalbed, generate nginx index file.
|
||||
if [ $__SRS_BUILD_NGINX = YES ]; then
|
||||
rm -f ${SRS_OBJS}/nginx/html/index.html &&
|
||||
ln -sf `pwd`/research/players/nginx_index.html ${SRS_OBJS}/nginx/html/index.html
|
||||
if [[ $SRS_SSL == YES && $SRS_USE_SYS_SSL == YES ]]; then
|
||||
echo "Warning: Use system libssl, without compiling openssl."
|
||||
fi
|
||||
if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
||||
# if http-server enalbed, use srs embeded http-server
|
||||
rm -f ${SRS_OBJS}/nginx/html/index.html &&
|
||||
ln -sf `pwd`/research/players/srs-http-server_index.html ${SRS_OBJS}/nginx/html/index.html
|
||||
# if api-server enabled, generate for api server.
|
||||
rm -f ${SRS_OBJS}/nginx/html/index.html &&
|
||||
ln -sf `pwd`/research/players/api-server_index.html ${SRS_OBJS}/nginx/html/index.html
|
||||
fi
|
||||
|
||||
#####################################################################################
|
||||
# openssl, for rtmp complex handshake
|
||||
#####################################################################################
|
||||
# extra configure options
|
||||
CONFIGURE_TOOL="./config"
|
||||
if [ $SRS_CROSS_BUILD = YES ]; then
|
||||
CONFIGURE_TOOL="./Configure linux-armv4"
|
||||
fi
|
||||
if [ $SRS_OSX = YES ]; then
|
||||
CONFIGURE_TOOL="./Configure darwin64-`uname -m`-cc"
|
||||
fi
|
||||
OPENSSL_HOTFIX="-DOPENSSL_NO_HEARTBEATS"
|
||||
# @see http://www.openssl.org/news/secadv/20140407.txt
|
||||
# Affected users should upgrade to OpenSSL 1.1.0e. Users unable to immediately
|
||||
# upgrade can alternatively recompile OpenSSL with -DOPENSSL_NO_HEARTBEATS.
|
||||
if [ $SRS_SSL = YES ]; then
|
||||
if [[ -f /usr/local/lib64/libssl.a && ! -f ${SRS_OBJS}/openssl/lib/libssl.a ]]; then
|
||||
(mkdir -p ${SRS_OBJS}/openssl/lib && cd ${SRS_OBJS}/openssl/lib &&
|
||||
ln -sf /usr/local/lib64/libssl.a && ln -sf /usr/local/lib64/libcrypto.a)
|
||||
(mkdir -p ${SRS_OBJS}/openssl/include && cd ${SRS_OBJS}/openssl/include &&
|
||||
ln -sf /usr/local/include/openssl)
|
||||
fi
|
||||
if [ $SRS_USE_SYS_SSL = YES ]; then
|
||||
echo "Warning: Use system libssl, without compiling openssl."
|
||||
if [[ $SRS_SSL == YES && $SRS_USE_SYS_SSL != YES ]]; then
|
||||
OPENSSL_OPTIONS="-no-shared -no-threads -no-asm -DOPENSSL_NO_HEARTBEATS"
|
||||
OPENSSL_CONFIG="./config"
|
||||
# https://stackoverflow.com/questions/15539062/cross-compiling-of-openssl-for-linux-arm-v5te-linux-gnueabi-toolchain
|
||||
if [[ $SRS_CROSS_BUILD == YES ]]; then
|
||||
OPENSSL_CONFIG="./Configure linux-armv4"
|
||||
else
|
||||
# check the cross build flag file, if flag changed, need to rebuild the st.
|
||||
if [ $SRS_CROSS_BUILD = YES ]; then
|
||||
# ok, arm specified, if the flag filed does not exists, need to rebuild.
|
||||
if [[ -f ${SRS_OBJS}/_flag.ssl.cross.build.tmp && -f ${SRS_OBJS}/openssl/lib/libssl.a ]]; then
|
||||
echo "The openssl-1.1.0e for arm is ok.";
|
||||
else
|
||||
echo "Building openssl-1.1.0e for ARM.";
|
||||
(
|
||||
rm -rf ${SRS_OBJS}/openssl-1.1.0e && cd ${SRS_OBJS} &&
|
||||
unzip -q ../3rdparty/openssl-1.1.0e.zip && cd openssl-1.1.0e &&
|
||||
$CONFIGURE_TOOL --prefix=`pwd`/_release -no-shared no-asm no-threads $OPENSSL_HOTFIX &&
|
||||
make CC=${SrsArmCC} GCC=${SrsArmGCC} AR="${SrsArmAR} r" \
|
||||
LD=${SrsArmLD} LINK=${SrsArmGCC} RANDLIB=${SrsArmRANDLIB} &&
|
||||
make install_sw &&
|
||||
cd .. && rm -rf openssl && ln -sf openssl-1.1.0e/_release openssl &&
|
||||
cd .. && touch ${SRS_OBJS}/_flag.ssl.cross.build.tmp
|
||||
)
|
||||
fi
|
||||
else
|
||||
# cross build not specified, if exists flag, need to rebuild for no-arm platform.
|
||||
if [[ ! -f ${SRS_OBJS}/_flag.ssl.cross.build.tmp && -f ${SRS_OBJS}/openssl/lib/libssl.a ]]; then
|
||||
echo "Openssl-1.1.0e is ok.";
|
||||
else
|
||||
echo "Building openssl-1.1.0e.";
|
||||
(
|
||||
rm -rf ${SRS_OBJS}/openssl-1.1.0e && cd ${SRS_OBJS} &&
|
||||
unzip -q ../3rdparty/openssl-1.1.0e.zip && cd openssl-1.1.0e &&
|
||||
$CONFIGURE_TOOL --prefix=`pwd`/_release -no-shared no-threads $OPENSSL_HOTFIX &&
|
||||
make && make install_sw &&
|
||||
cd .. && rm -rf openssl && ln -sf openssl-1.1.0e/_release openssl &&
|
||||
cd .. && rm -f ${SRS_OBJS}/_flag.ssl.cross.build.tmp
|
||||
)
|
||||
fi
|
||||
# If not crossbuild, try to use exists libraries.
|
||||
if [[ -f /usr/local/lib64/libssl.a && ! -f ${SRS_OBJS}/openssl/lib/libssl.a ]]; then
|
||||
(mkdir -p ${SRS_OBJS}/openssl/lib && cd ${SRS_OBJS}/openssl/lib &&
|
||||
ln -sf /usr/local/lib64/libssl.a && ln -sf /usr/local/lib64/libcrypto.a)
|
||||
(mkdir -p ${SRS_OBJS}/openssl/include && cd ${SRS_OBJS}/openssl/include &&
|
||||
ln -sf /usr/local/include/openssl)
|
||||
fi
|
||||
# check status
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then echo "Build openssl-1.1.0e failed, ret=$ret"; exit $ret; fi
|
||||
if [ ! -f ${SRS_OBJS}/openssl/lib/libssl.a ]; then echo "Build openssl-1.1.0e failed."; exit -1; fi
|
||||
fi
|
||||
# cross build not specified, if exists flag, need to rebuild for no-arm platform.
|
||||
if [[ -f ${SRS_OBJS}/openssl/lib/libssl.a ]]; then
|
||||
echo "Openssl-1.1.0e is ok.";
|
||||
else
|
||||
echo "Building openssl-1.1.0e.";
|
||||
(
|
||||
rm -rf ${SRS_OBJS}/openssl-1.1.0e && cd ${SRS_OBJS} &&
|
||||
unzip -q ../3rdparty/openssl-1.1.0e.zip && cd openssl-1.1.0e &&
|
||||
${OPENSSL_CONFIG} --prefix=`pwd`/_release $OPENSSL_OPTIONS &&
|
||||
make CC=${SRS_TOOL_CC} AR="${SRS_TOOL_AR} -rs" LD=${SRS_TOOL_LD} RANDLIB=${SRS_TOOL_RANDLIB} && make install_sw &&
|
||||
cd .. && rm -rf openssl && ln -sf openssl-1.1.0e/_release openssl
|
||||
)
|
||||
fi
|
||||
# check status
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then echo "Build openssl-1.1.0e failed, ret=$ret"; exit $ret; fi
|
||||
if [ ! -f ${SRS_OBJS}/openssl/lib/libssl.a ]; then echo "Build openssl-1.1.0e failed."; exit -1; fi
|
||||
fi
|
||||
|
||||
#####################################################################################
|
||||
# live transcoding, ffmpeg-4.1, x264-core157, lame-3.99.5, libaacplus-2.0.2.
|
||||
#####################################################################################
|
||||
# Always link the ffmpeg tools if exists.
|
||||
if [[ -f /usr/local/bin/ffmpeg && ! -f ${SRS_OBJS}/ffmpeg/bin/ffmpeg ]]; then
|
||||
mkdir -p ${SRS_OBJS}/ffmpeg/bin && ln -sf /usr/local/bin/ffmpeg ${SRS_OBJS}/ffmpeg/bin/ffmpeg
|
||||
fi
|
||||
if [ $SRS_FFMPEG_TOOL = YES ]; then
|
||||
if [[ -f /usr/local/bin/ffmpeg && ! -f ${SRS_OBJS}/ffmpeg/bin/ffmpeg ]]; then
|
||||
mkdir -p ${SRS_OBJS}/ffmpeg/bin && ln -sf /usr/local/bin/ffmpeg ${SRS_OBJS}/ffmpeg/bin/ffmpeg
|
||||
fi
|
||||
if [[ -f ${SRS_OBJS}/ffmpeg/bin/ffmpeg ]]; then
|
||||
echo "ffmpeg-4.1 is ok.";
|
||||
else
|
||||
|
@ -767,4 +454,3 @@ fi
|
|||
# generated the test script
|
||||
#####################################################################################
|
||||
rm -rf ${SRS_OBJS}/srs.test && ln -sf `pwd`/scripts/srs.test objs/srs.test
|
||||
|
||||
|
|
|
@ -1,12 +1,5 @@
|
|||
#!/bin/bash
|
||||
|
||||
OS_IS_OSX=NO
|
||||
uname -s|grep Darwin >/dev/null 2>&1
|
||||
ret=$?; if [[ 0 -eq $ret ]]; then
|
||||
OS_IS_OSX=YES
|
||||
fi
|
||||
echo "Is OSX: ${OS_IS_OSX}"
|
||||
|
||||
# when export srs-librtmp single files
|
||||
# package the whole project to srs_librtmp.h and srs_librtmp.cpp
|
||||
#
|
||||
|
@ -127,14 +120,14 @@ int main(int argc, char** argv)
|
|||
|
||||
END
|
||||
|
||||
# compile the example
|
||||
(cd $SRS_EXPORT_LIBRTMP_SINGLE && echo "${SRS_SINGLE_LIBRTMP_COMPILE}" &&
|
||||
`${SRS_SINGLE_LIBRTMP_COMPILE}` && ./example && rm -f example)
|
||||
ret=$?; if [[ $ret -ne 0 ]]; then
|
||||
echo "(cd $SRS_EXPORT_LIBRTMP_SINGLE && ${SRS_SINGLE_LIBRTMP_COMPILE} && ./example && rm -f example)"
|
||||
echo -e "${RED}failed to compile example.${BLACK}"
|
||||
exit $ret
|
||||
fi
|
||||
## compile the example
|
||||
#(cd $SRS_EXPORT_LIBRTMP_SINGLE && echo "${SRS_SINGLE_LIBRTMP_COMPILE}" &&
|
||||
#`${SRS_SINGLE_LIBRTMP_COMPILE}` && ./example && rm -f example)
|
||||
#ret=$?; if [[ $ret -ne 0 ]]; then
|
||||
# echo "(cd $SRS_EXPORT_LIBRTMP_SINGLE && ${SRS_SINGLE_LIBRTMP_COMPILE} && ./example && rm -f example)"
|
||||
# echo -e "${RED}failed to compile example.${BLACK}"
|
||||
# exit $ret
|
||||
#fi
|
||||
|
||||
# clear the files for srs-librtmp project, generated by generate-srs-librtmp-project.sh
|
||||
(cd $SRS_EXPORT_LIBRTMP_SINGLE && rm -rf auto $SRS_OBJS_DIR research src Makefile)
|
||||
|
|
|
@ -19,6 +19,7 @@ echo "Generating lib ${LIB_NAME} depends."
|
|||
echo "" >> ${FILE}
|
||||
echo "# archive library ${LIB_TAGET_STATIC}" >> ${FILE}
|
||||
echo "${BUILD_KEY}: ${LIB_TAGET_STATIC}" >> ${FILE}
|
||||
echo "" >> ${FILE}
|
||||
|
||||
# build depends
|
||||
echo -n "${LIB_TAGET_STATIC}: " >> ${FILE}
|
||||
|
|
|
@ -18,9 +18,8 @@ help=no
|
|||
SRS_HDS=NO
|
||||
SRS_NGINX=NO
|
||||
SRS_FFMPEG_TOOL=NO
|
||||
SRS_KAFKA=NO
|
||||
SRS_LIBRTMP=NO
|
||||
SRS_RESEARCH=YES
|
||||
SRS_RESEARCH=NO
|
||||
SRS_UTEST=YES
|
||||
SRS_GPERF=NO # Performance test: tcmalloc
|
||||
SRS_GPERF_MC=NO # Performance test: gperf memory check
|
||||
|
@ -48,6 +47,8 @@ SRS_FFMPEG_STUB=NO
|
|||
SRS_PREFIX=/usr/local/srs
|
||||
SRS_JOBS=1
|
||||
SRS_STATIC=NO
|
||||
# If enabled, link shared libraries for libst.so which uses MPL license.
|
||||
SRS_SHARED_ST=NO
|
||||
# whether enable the gcov
|
||||
SRS_GCOV=NO
|
||||
# whether enable the log verbose/info/trace level.
|
||||
|
@ -76,11 +77,6 @@ SRS_VALGRIND=NO
|
|||
SRS_X86_X64=NO
|
||||
# for osx system
|
||||
SRS_OSX=NO
|
||||
SRS_ALLOW_OSX=NO
|
||||
# armhf(v7cpu) built on ubuntu12
|
||||
SRS_ARM_UBUNTU12=NO
|
||||
# mips built on ubuntu12
|
||||
SRS_MIPS_UBUNTU12=NO
|
||||
# dev, open all features for dev, no gperf/prof/arm.
|
||||
SRS_DEV=NO
|
||||
# dev, open main server feature for dev, no utest/research/librtmp
|
||||
|
@ -100,9 +96,15 @@ SRS_DISABLE_ALL=NO
|
|||
# all features is on
|
||||
SRS_ENABLE_ALL=NO
|
||||
#
|
||||
################################################################
|
||||
# whether cross build for embed cpu, arm/mips
|
||||
#####################################################################################
|
||||
# Toolchain crossbuild for ARM or MIPS.
|
||||
SRS_CROSS_BUILD=NO
|
||||
SRS_TOOL_CC=gcc
|
||||
SRS_TOOL_CXX=g++
|
||||
SRS_TOOL_AR=ar
|
||||
SRS_TOOL_LD=ld
|
||||
SRS_TOOL_RANDLIB=randlib
|
||||
SRS_EXTRA_FLAGS=
|
||||
|
||||
#####################################################################################
|
||||
# menu
|
||||
|
@ -110,109 +112,88 @@ SRS_CROSS_BUILD=NO
|
|||
function show_help() {
|
||||
cat << END
|
||||
|
||||
Options:
|
||||
-h, --help print this message
|
||||
|
||||
--with-ssl enable rtmp complex handshake, requires openssl-devel installed.
|
||||
--with-hds enable hds streaming, mux RTMP to F4M/F4V files.
|
||||
--with-nginx enable delivery HTTP stream with nginx.
|
||||
--with-stream-caster enable stream caster to serve other stream over other protocol.
|
||||
--with-kafka enable srs kafka producer to report to kafka.
|
||||
--with-ffmpeg enable transcoding tool ffmpeg.
|
||||
--with-transcode enable transcoding features.
|
||||
--with-ingest enable ingest features.
|
||||
--with-stat enable the data statistic, for http api.
|
||||
--with-librtmp enable srs-librtmp, library for client.
|
||||
--with-research build the research tools.
|
||||
--with-utest build the utest for SRS.
|
||||
--with-gperf build SRS with gperf tools(no gmd/gmc/gmp/gcp, with tcmalloc only).
|
||||
--with-gmc build memory check for SRS with gperf tools.
|
||||
--with-gmd build memory defense(corrupt memory) for SRS with gperf tools.
|
||||
--with-gmp build memory profile for SRS with gperf tools.
|
||||
--with-gcp build cpu profile for SRS with gperf tools.
|
||||
--with-gprof build SRS with gprof(GNU profile tool).
|
||||
--with-arm-ubuntu12 cross build SRS on ubuntu12 for armhf(v7cpu).
|
||||
--with-mips-ubuntu12 cross build SRS on ubuntu12 for mips.
|
||||
|
||||
--without-ssl disable rtmp complex handshake.
|
||||
--without-hds disable hds, the adobe http dynamic streaming.
|
||||
--without-nginx disable delivery HTTP stream with nginx.
|
||||
--without-stream-caster disable stream caster, only listen and serve RTMP/HTTP.
|
||||
--without-kafka disable the srs kafka producer.
|
||||
--without-ffmpeg disable the ffmpeg transcode tool feature.
|
||||
--without-transcode disable the transcoding feature.
|
||||
--without-ingest disable the ingest feature.
|
||||
--without-stat disable the data statistic feature.
|
||||
--without-librtmp disable srs-librtmp, library for client.
|
||||
--without-research do not build the research tools.
|
||||
--without-utest do not build the utest for SRS.
|
||||
--without-gperf do not build SRS with gperf tools(without tcmalloc and gmd/gmc/gmp/gcp).
|
||||
--without-gmc do not build memory check for SRS with gperf tools.
|
||||
--without-gmd do not build memory defense for SRS with gperf tools.
|
||||
--without-gmp do not build memory profile for SRS with gperf tools.
|
||||
--without-gcp do not build cpu profile for SRS with gperf tools.
|
||||
--without-gprof do not build srs with gprof(GNU profile tool).
|
||||
--without-arm-ubuntu12 do not cross build srs on ubuntu12 for armhf(v7cpu).
|
||||
--without-mips-ubuntu12 do not cross build srs on ubuntu12 for mips.
|
||||
|
||||
Presets:
|
||||
--x86-64, --x86-x64 [default] For x86/x64 cpu, common pc and servers.
|
||||
--arm Enable crossbuild for ARM, should also set bellow toolchain options.
|
||||
--mips Enable crossbuild for MIPS
|
||||
|
||||
Features:
|
||||
-h, --help Print this message and exit 0.
|
||||
|
||||
--with-ssl Enable rtmp complex handshake, requires openssl-devel installed.
|
||||
--with-hds Enable hds streaming, mux RTMP to F4M/F4V files.
|
||||
--with-stream-caster Enable stream caster to serve other stream over other protocol.
|
||||
--with-stat Enable the data statistic, for http api.
|
||||
--with-librtmp Enable srs-librtmp, library for client.
|
||||
--with-research Build the research tools.
|
||||
--with-utest Build the utest for SRS.
|
||||
|
||||
--without-ssl Disable rtmp complex handshake.
|
||||
--without-hds Disable hds, the adobe http dynamic streaming.
|
||||
--without-stream-caster Disable stream caster, only listen and serve RTMP/HTTP.
|
||||
--without-stat Disable the data statistic feature.
|
||||
--without-librtmp Disable srs-librtmp, library for client.
|
||||
--without-research Do not build the research tools.
|
||||
--without-utest Do not build the utest for SRS.
|
||||
|
||||
--prefix=<path> The absolute installation path for srs. Default: $SRS_PREFIX
|
||||
--static Whether add '-static' to link options.
|
||||
--gcov Whether enable the GCOV compiler options.
|
||||
--jobs[=N] Allow N jobs at once; infinite jobs with no arg.
|
||||
used for make in the configure, for example, to make ffmpeg.
|
||||
--log-verbose whether enable the log verbose level. default: no.
|
||||
--log-info whether enable the log info level. default: no.
|
||||
--log-trace whether enable the log trace level. default: yes.
|
||||
Used for make in the configure, for example, to make ffmpeg.
|
||||
--log-verbose Whether enable the log verbose level. default: no.
|
||||
--log-info Whether enable the log info level. default: no.
|
||||
--log-trace Whether enable the log trace level. default: yes.
|
||||
|
||||
Presets:
|
||||
--x86-x64 [default] for x86/x64 cpu, common pc and servers.
|
||||
--osx for osx(darwin) system to build SRS.
|
||||
--pi for raspberry-pi(directly build), open features hls/ssl/static.
|
||||
--cubie for cubieboard(directly build), open features except ffmpeg/nginx.
|
||||
--arm alias for --with-arm-ubuntu12, for ubuntu12, arm crossbuild
|
||||
--mips alias for --with-mips-ubuntu12, for ubuntu12, mips crossbuild
|
||||
--fast the most fast compile, nothing, only support vp6 RTMP.
|
||||
--pure-rtmp only support RTMP with ssl.
|
||||
--disable-all disable all features, only support vp6 RTMP.
|
||||
--dev for dev, open all features, no nginx/gperf/gprof/arm.
|
||||
--fast-dev for dev fast compile, the RTMP server, without librtmp/utest/research.
|
||||
--demo for srs demo, @see: https://github.com/ossrs/srs/wiki/v1_CN_SampleDemo
|
||||
--full enable all features, no gperf/gprof/arm.
|
||||
--x86-64 alias for --x86-x64.
|
||||
Performance: @see https://blog.csdn.net/win_lin/article/details/53503869
|
||||
--with-valgrind Support valgrind for memory check.
|
||||
--with-gperf Build SRS with gperf tools(no gmd/gmc/gmp/gcp, with tcmalloc only).
|
||||
--with-gmc Build memory check for SRS with gperf tools.
|
||||
--with-gmd Build memory defense(corrupt memory) for SRS with gperf tools.
|
||||
--with-gmp Build memory profile for SRS with gperf tools.
|
||||
--with-gcp Build cpu profile for SRS with gperf tools.
|
||||
--with-gprof Build SRS with gprof(GNU profile tool).
|
||||
|
||||
--without-valgrind Do not support valgrind for memory check.
|
||||
--without-gperf Do not build SRS with gperf tools(without tcmalloc and gmd/gmc/gmp/gcp).
|
||||
--without-gmc Do not build memory check for SRS with gperf tools.
|
||||
--without-gmd Do not build memory defense for SRS with gperf tools.
|
||||
--without-gmp Do not build memory profile for SRS with gperf tools.
|
||||
--without-gcp Do not build cpu profile for SRS with gperf tools.
|
||||
--without-gprof Do not build srs with gprof(GNU profile tool).
|
||||
|
||||
Toolchain options: @see https://github.com/ossrs/srs/issues/1547#issuecomment-576078411
|
||||
--arm Enable crossbuild for ARM.
|
||||
--mips Enable crossbuild for MIPS.
|
||||
--cc=<CC> Use c compiler CC, default is gcc.
|
||||
--cxx=<CXX> Use c++ compiler CXX, default is g++.
|
||||
--ar=<AR> Use archive tool AR, default is ar.
|
||||
--ld=<LD> Use linker tool LD, default is ld.
|
||||
--randlib=<RANDLIB> Use randlib tool RANDLIB, default is randlib.
|
||||
--extra-flags=<EFLAGS> Set EFLAGS as CFLAGS and CXXFLAGS. Also passed to ST as EXTRA_CFLAGS.
|
||||
|
||||
Always Enabled:
|
||||
--with-http-api enable HTTP API, to communicate with SRS.
|
||||
--with-http-callback enable HTTP hooks, build cherrypy as demo api server.
|
||||
--with-http-server enable HTTP server to delivery http stream.
|
||||
--with-hls enable HLS streaming, mux RTMP to M3U8/TS files.
|
||||
--with-dvr enable DVR, record RTMP to FLV/MP4 files.
|
||||
|
||||
Conflicts:
|
||||
1. --with-gmc vs --with-gmp:
|
||||
@see: http://google-perftools.googlecode.com/svn/trunk/doc/heap_checker.html
|
||||
2. --with-gperf/gmc/gmp vs --with-gprof:
|
||||
gperftools not compatible with gprof.
|
||||
The gperftools not compatible with gprof.
|
||||
3. --arm vs --with-ffmpeg/gperf/gmc/gmp/gprof:
|
||||
the complex tools not available for arm.
|
||||
The complex tools not available for arm.
|
||||
|
||||
Experts:
|
||||
--use-sys-ssl donot compile ssl, use system ssl(-lssl) if required.
|
||||
--memory-watch enable memory watch to detect memory leaking(hurts performance).
|
||||
--export-librtmp-project=<path> export srs-librtmp to specified project in path.
|
||||
--export-librtmp-single=<path> export srs-librtmp to a single file(.h+.cpp) in path.
|
||||
--without-valgrind donot support valgrind for memory check.
|
||||
--use-sys-ssl Do not compile ssl, use system ssl(-lssl) if required.
|
||||
--use-shared-st Use link shared libraries for ST which uses MPL license.
|
||||
--export-librtmp-project=<path> Export srs-librtmp to specified project in path.
|
||||
--export-librtmp-single=<path> Export srs-librtmp to a single file(.h+.cpp) in path.
|
||||
|
||||
Workflow:
|
||||
1. apply "Presets". if not specified, use default preset.
|
||||
2. apply "Options". user specified option will override the preset.
|
||||
3. check conflicts. @see Conflicts section.
|
||||
4. generate detail features.
|
||||
1. Apply "Presets". if not specified, use default preset.
|
||||
2. Apply "Features", "Performance" and others. user specified option will override the preset.
|
||||
3. Check conflicts, fail if exists conflicts.
|
||||
4. Generate Makefile.
|
||||
|
||||
Remark:
|
||||
1. both ubuntu12 and ubuntu14 are ok for SRS.
|
||||
2. the centos5, centos6 and centos7 are ok for SRS.
|
||||
3. all linux and unix-like os are ok for SRS.
|
||||
4. windows is absolutely impossible for SRS.
|
||||
1. For performance improving, read https://blog.csdn.net/win_lin/article/details/53503869
|
||||
|
||||
END
|
||||
}
|
||||
|
@ -230,7 +211,6 @@ function parse_user_option() {
|
|||
--with-ingest) SRS_INGEST=YES ;;
|
||||
--with-stat) SRS_STAT=YES ;;
|
||||
--with-stream-caster) SRS_STREAM_CASTER=YES ;;
|
||||
--with-kafka) SRS_KAFKA=YES ;;
|
||||
--with-librtmp) SRS_LIBRTMP=YES ;;
|
||||
--with-research) SRS_RESEARCH=YES ;;
|
||||
--with-utest) SRS_UTEST=YES ;;
|
||||
|
@ -240,18 +220,12 @@ function parse_user_option() {
|
|||
--with-gmp) SRS_GPERF_MP=YES ;;
|
||||
--with-gcp) SRS_GPERF_CP=YES ;;
|
||||
--with-gprof) SRS_GPROF=YES ;;
|
||||
--with-arm-ubuntu12) SRS_ARM_UBUNTU12=YES ;;
|
||||
--with-mips-ubuntu12) SRS_MIPS_UBUNTU12=YES ;;
|
||||
|
||||
--without-ssl) SRS_SSL=NO ;;
|
||||
--with-arm-ubuntu12) SRS_CROSS_BUILD=YES ;;
|
||||
--with-mips-ubuntu12) SRS_CROSS_BUILD=YES ;;
|
||||
|
||||
--without-hds) SRS_HDS=NO ;;
|
||||
--without-nginx) SRS_NGINX=NO ;;
|
||||
--without-ffmpeg) SRS_FFMPEG_TOOL=NO ;;
|
||||
--without-transcode) SRS_TRANSCODE=NO ;;
|
||||
--without-ingest) SRS_INGEST=NO ;;
|
||||
--without-stat) SRS_STAT=NO ;;
|
||||
--without-stream-caster) SRS_STREAM_CASTER=NO ;;
|
||||
--without-kafka) SRS_KAFKA=NO ;;
|
||||
--without-librtmp) SRS_LIBRTMP=NO ;;
|
||||
--without-research) SRS_RESEARCH=NO ;;
|
||||
--without-utest) SRS_UTEST=NO ;;
|
||||
|
@ -261,8 +235,8 @@ function parse_user_option() {
|
|||
--without-gmp) SRS_GPERF_MP=NO ;;
|
||||
--without-gcp) SRS_GPERF_CP=NO ;;
|
||||
--without-gprof) SRS_GPROF=NO ;;
|
||||
--without-arm-ubuntu12) SRS_ARM_UBUNTU12=NO ;;
|
||||
--without-mips-ubuntu12) SRS_MIPS_UBUNTU12=NO ;;
|
||||
--without-arm-ubuntu12) SRS_CROSS_BUILD=NO ;;
|
||||
--without-mips-ubuntu12) SRS_CROSS_BUILD=NO ;;
|
||||
|
||||
--jobs) SRS_JOBS=${value} ;;
|
||||
--prefix) SRS_PREFIX=${value} ;;
|
||||
|
@ -271,13 +245,20 @@ function parse_user_option() {
|
|||
--log-info) SRS_LOG_INFO=YES ;;
|
||||
--log-trace) SRS_LOG_TRACE=YES ;;
|
||||
--gcov) SRS_GCOV=YES ;;
|
||||
|
||||
|
||||
--arm) SRS_CROSS_BUILD=YES ;;
|
||||
--mips) SRS_CROSS_BUILD=YES ;;
|
||||
--cc) SRS_TOOL_CC=${value} ;;
|
||||
--cxx) SRS_TOOL_CXX=${value} ;;
|
||||
--ar) SRS_TOOL_AR=${value} ;;
|
||||
--ld) SRS_TOOL_LD=${value} ;;
|
||||
--randlib) SRS_TOOL_RANDLIB=${value} ;;
|
||||
--extra-flags) SRS_EXTRA_FLAGS=${value} ;;
|
||||
|
||||
--x86-x64) SRS_X86_X64=YES ;;
|
||||
--x86-64) SRS_X86_X64=YES ;;
|
||||
--osx) SRS_OSX=YES ;;
|
||||
--allow-osx) SRS_ALLOW_OSX=YES ;;
|
||||
--arm) SRS_ARM_UBUNTU12=YES ;;
|
||||
--mips) SRS_MIPS_UBUNTU12=YES ;;
|
||||
--allow-osx) SRS_OSX=YES ;;
|
||||
--pi) SRS_PI=YES ;;
|
||||
--cubie) SRS_CUBIE=YES ;;
|
||||
--dev) SRS_DEV=YES ;;
|
||||
|
@ -289,9 +270,12 @@ function parse_user_option() {
|
|||
--full) SRS_ENABLE_ALL=YES ;;
|
||||
|
||||
--use-sys-ssl) SRS_USE_SYS_SSL=YES ;;
|
||||
--use-shared-st) SRS_SHARED_ST=YES ;;
|
||||
|
||||
--memory-watch) SRS_MEM_WATCH=YES ;;
|
||||
--export-librtmp-project) SRS_EXPORT_LIBRTMP_PROJECT=${value} ;;
|
||||
--export-librtmp-single) SRS_EXPORT_LIBRTMP_SINGLE=${value} ;;
|
||||
--with-valgrind) SRS_VALGRIND=YES ;;
|
||||
--without-valgrind) SRS_VALGRIND=NO ;;
|
||||
|
||||
--with-http-callback) SRS_HTTP_CALLBACK=YES ;;
|
||||
|
@ -299,11 +283,19 @@ function parse_user_option() {
|
|||
--with-http-server) SRS_HTTP_SERVER=YES ;;
|
||||
--with-hls) SRS_HLS=YES ;;
|
||||
--with-dvr) SRS_DVR=YES ;;
|
||||
--without-http-callback) SRS_HTTP_CALLBACK=NO ;;
|
||||
--without-http-api) SRS_HTTP_API=NO ;;
|
||||
--without-http-server) SRS_HTTP_SERVER=NO ;;
|
||||
--without-hls) SRS_HLS=NO ;;
|
||||
--without-dvr) SRS_DVR=NO ;;
|
||||
|
||||
--without-stream-caster) ;&
|
||||
--without-ingest) ;&
|
||||
--without-ssl) ;&
|
||||
--without-stat) ;&
|
||||
--without-transcode) ;&
|
||||
--without-http-callback) ;&
|
||||
--without-http-server) ;&
|
||||
--without-http-api) ;&
|
||||
--without-hls) ;&
|
||||
--without-dvr)
|
||||
echo "ignore option \"$option\""
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "$0: error: invalid option \"$option\""
|
||||
|
@ -315,8 +307,8 @@ function parse_user_option() {
|
|||
function parse_user_option_to_value_and_option() {
|
||||
case "$option" in
|
||||
-*=*)
|
||||
value=`echo "$option" | sed -e 's|[-_a-zA-Z0-9/]*=||'`
|
||||
option=`echo "$option" | sed -e 's|=[-_a-zA-Z0-9/.]*||'`
|
||||
value=`echo "$option" | sed -e 's|[-_a-zA-Z0-9/]*=||'`
|
||||
option=`echo "$option" | sed -e 's|=[-_a-zA-Z0-9/. +]*||'`
|
||||
;;
|
||||
*) value="" ;;
|
||||
esac
|
||||
|
@ -346,48 +338,16 @@ function apply_user_presets() {
|
|||
SRS_LOG_TRACE=YES
|
||||
|
||||
# set default preset if not specifies
|
||||
if [ $SRS_PURE_RTMP = NO ]; then
|
||||
if [ $SRS_FAST = NO ]; then
|
||||
if [ $SRS_DISABLE_ALL = NO ]; then
|
||||
if [ $SRS_ENABLE_ALL = NO ]; then
|
||||
if [ $SRS_DEV = NO ]; then
|
||||
if [ $SRS_FAST_DEV = NO ]; then
|
||||
if [ $SRS_DEMO = NO ]; then
|
||||
if [ $SRS_ARM_UBUNTU12 = NO ]; then
|
||||
if [ $SRS_MIPS_UBUNTU12 = NO ]; then
|
||||
if [ $SRS_PI = NO ]; then
|
||||
if [ $SRS_CUBIE = NO ]; then
|
||||
if [ $SRS_X86_X64 = NO ]; then
|
||||
if [ $SRS_OSX = NO ]; then
|
||||
SRS_X86_X64=YES; opt="--x86-x64 $opt";
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# whether embeded cpu.
|
||||
if [ $SRS_ARM_UBUNTU12 = YES ]; then
|
||||
SRS_CROSS_BUILD=YES
|
||||
fi
|
||||
if [ $SRS_MIPS_UBUNTU12 = YES ]; then
|
||||
SRS_CROSS_BUILD=YES
|
||||
if [[ $SRS_PURE_RTMP == NO && $SRS_FAST == NO && $SRS_DISABLE_ALL == NO && $SRS_ENABLE_ALL == NO && \
|
||||
$SRS_DEV == NO && $SRS_FAST_DEV == NO && $SRS_DEMO == NO && $SRS_PI == NO && $SRS_CUBIE == NO && \
|
||||
$SRS_X86_X64 == NO && $SRS_OSX == NO && $SRS_CROSS_BUILD == NO \
|
||||
]]; then
|
||||
SRS_X86_X64=YES; opt="--x86-x64 $opt";
|
||||
fi
|
||||
|
||||
# all disabled.
|
||||
if [ $SRS_DISABLE_ALL = YES ]; then
|
||||
SRS_HDS=NO
|
||||
SRS_NGINX=NO
|
||||
SRS_FFMPEG_TOOL=NO
|
||||
SRS_KAFKA=NO
|
||||
SRS_LIBRTMP=NO
|
||||
SRS_RESEARCH=NO
|
||||
SRS_UTEST=NO
|
||||
|
@ -397,9 +357,6 @@ function apply_user_presets() {
|
|||
# all enabled.
|
||||
if [ $SRS_ENABLE_ALL = YES ]; then
|
||||
SRS_HDS=YES
|
||||
SRS_NGINX=YES
|
||||
SRS_FFMPEG_TOOL=YES
|
||||
SRS_KAFKA=YES
|
||||
SRS_LIBRTMP=YES
|
||||
SRS_RESEARCH=YES
|
||||
SRS_UTEST=YES
|
||||
|
@ -409,9 +366,6 @@ function apply_user_presets() {
|
|||
# only rtmp vp6
|
||||
if [ $SRS_FAST = YES ]; then
|
||||
SRS_HDS=NO
|
||||
SRS_NGINX=NO
|
||||
SRS_FFMPEG_TOOL=NO
|
||||
SRS_KAFKA=NO
|
||||
SRS_LIBRTMP=NO
|
||||
SRS_RESEARCH=NO
|
||||
SRS_UTEST=NO
|
||||
|
@ -421,73 +375,24 @@ function apply_user_presets() {
|
|||
# only ssl for RTMP with complex handshake.
|
||||
if [ $SRS_PURE_RTMP = YES ]; then
|
||||
SRS_HDS=NO
|
||||
SRS_NGINX=NO
|
||||
SRS_FFMPEG_TOOL=NO
|
||||
SRS_KAFKA=NO
|
||||
SRS_LIBRTMP=NO
|
||||
SRS_RESEARCH=NO
|
||||
SRS_UTEST=NO
|
||||
SRS_STATIC=NO
|
||||
fi
|
||||
|
||||
# if arm specified, set some default to disabled.
|
||||
if [ $SRS_ARM_UBUNTU12 = YES ]; then
|
||||
SRS_HDS=YES
|
||||
SRS_NGINX=NO
|
||||
SRS_FFMPEG_TOOL=NO
|
||||
SRS_KAFKA=YES
|
||||
SRS_LIBRTMP=YES
|
||||
SRS_RESEARCH=NO
|
||||
SRS_UTEST=NO
|
||||
# TODO: FIXME: need static? maybe donot.
|
||||
SRS_STATIC=YES
|
||||
fi
|
||||
|
||||
# if mips specified, set some default to disabled.
|
||||
if [ $SRS_MIPS_UBUNTU12 = YES ]; then
|
||||
SRS_HDS=YES
|
||||
SRS_NGINX=NO
|
||||
SRS_FFMPEG_TOOL=NO
|
||||
SRS_KAFKA=YES
|
||||
SRS_LIBRTMP=YES
|
||||
SRS_RESEARCH=NO
|
||||
SRS_UTEST=NO
|
||||
SRS_STATIC=NO
|
||||
fi
|
||||
|
||||
# defaults for x86/x64
|
||||
if [ $SRS_X86_X64 = YES ]; then
|
||||
SRS_HDS=YES
|
||||
SRS_NGINX=NO
|
||||
SRS_FFMPEG_TOOL=NO
|
||||
SRS_KAFKA=YES
|
||||
SRS_LIBRTMP=YES
|
||||
SRS_RESEARCH=NO
|
||||
SRS_UTEST=YES
|
||||
SRS_STATIC=NO
|
||||
fi
|
||||
|
||||
# for osx(darwin)
|
||||
if [ $SRS_OSX = YES ]; then
|
||||
SRS_HDS=YES
|
||||
SRS_NGINX=NO
|
||||
SRS_FFMPEG_TOOL=NO
|
||||
SRS_KAFKA=YES
|
||||
SRS_LIBRTMP=YES
|
||||
SRS_RESEARCH=NO
|
||||
SRS_UTEST=YES
|
||||
SRS_STATIC=NO
|
||||
# valgrind is not supported by macOS sierra, read
|
||||
# https://stackoverflow.com/questions/40650338/valgrind-on-macos-sierra
|
||||
SRS_VALGRIND=NO
|
||||
fi
|
||||
|
||||
# if dev specified, open features if possible.
|
||||
if [ $SRS_DEV = YES ]; then
|
||||
SRS_HDS=YES
|
||||
SRS_NGINX=NO
|
||||
SRS_FFMPEG_TOOL=YES
|
||||
SRS_KAFKA=YES
|
||||
SRS_LIBRTMP=YES
|
||||
SRS_RESEARCH=YES
|
||||
SRS_UTEST=YES
|
||||
|
@ -497,9 +402,6 @@ function apply_user_presets() {
|
|||
# if fast dev specified, open main server features.
|
||||
if [ $SRS_FAST_DEV = YES ]; then
|
||||
SRS_HDS=YES
|
||||
SRS_NGINX=NO
|
||||
SRS_FFMPEG_TOOL=NO
|
||||
SRS_KAFKA=YES
|
||||
SRS_LIBRTMP=NO
|
||||
SRS_RESEARCH=NO
|
||||
SRS_UTEST=NO
|
||||
|
@ -509,9 +411,6 @@ function apply_user_presets() {
|
|||
# for srs demo
|
||||
if [ $SRS_DEMO = YES ]; then
|
||||
SRS_HDS=YES
|
||||
SRS_NGINX=NO
|
||||
SRS_FFMPEG_TOOL=YES
|
||||
SRS_KAFKA=YES
|
||||
SRS_LIBRTMP=YES
|
||||
SRS_RESEARCH=NO
|
||||
SRS_UTEST=YES
|
||||
|
@ -521,9 +420,6 @@ function apply_user_presets() {
|
|||
# if raspberry-pi specified, open ssl/hls/static features
|
||||
if [ $SRS_PI = YES ]; then
|
||||
SRS_HDS=YES
|
||||
SRS_NGINX=NO
|
||||
SRS_FFMPEG_TOOL=NO
|
||||
SRS_KAFKA=YES
|
||||
SRS_LIBRTMP=YES
|
||||
SRS_RESEARCH=NO
|
||||
SRS_UTEST=NO
|
||||
|
@ -533,14 +429,19 @@ function apply_user_presets() {
|
|||
# if cubieboard specified, open features except ffmpeg/nginx.
|
||||
if [ $SRS_CUBIE = YES ]; then
|
||||
SRS_HDS=YES
|
||||
SRS_NGINX=NO
|
||||
SRS_FFMPEG_TOOL=YES
|
||||
SRS_KAFKA=YES
|
||||
SRS_LIBRTMP=YES
|
||||
SRS_RESEARCH=NO
|
||||
SRS_UTEST=NO
|
||||
SRS_STATIC=NO
|
||||
fi
|
||||
|
||||
# if crossbuild, disable research and librtmp.
|
||||
if [[ $SRS_CROSS_BUILD == YES ]]; then
|
||||
SRS_LIBRTMP=NO
|
||||
SRS_RESEARCH=NO
|
||||
SRS_UTEST=NO
|
||||
SRS_STATIC=NO
|
||||
fi
|
||||
}
|
||||
apply_user_presets
|
||||
|
||||
|
@ -587,15 +488,12 @@ function apply_user_detail_options() {
|
|||
# disable almost all features for export srs-librtmp.
|
||||
if [ $SRS_EXPORT_LIBRTMP_PROJECT != NO ]; then
|
||||
SRS_HDS=NO
|
||||
SRS_NGINX=NO
|
||||
SRS_SSL=NO
|
||||
SRS_FFMPEG_TOOL=NO
|
||||
SRS_TRANSCODE=NO
|
||||
SRS_HTTP_CALLBACK=NO
|
||||
SRS_INGEST=NO
|
||||
SRS_STAT=NO
|
||||
SRS_STREAM_CASTER=NO
|
||||
SRS_KAFKA=NO
|
||||
SRS_LIBRTMP=YES
|
||||
SRS_RESEARCH=YES
|
||||
SRS_UTEST=NO
|
||||
|
@ -618,16 +516,13 @@ SRS_AUTO_CONFIGURE="--prefix=${SRS_PREFIX}"
|
|||
if [ $SRS_HLS = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-hls"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-hls"; fi
|
||||
if [ $SRS_HDS = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-hds"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-hds"; fi
|
||||
if [ $SRS_DVR = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-dvr"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-dvr"; fi
|
||||
if [ $SRS_NGINX = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-nginx"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-nginx"; fi
|
||||
if [ $SRS_SSL = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-ssl"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-ssl"; fi
|
||||
if [ $SRS_FFMPEG_TOOL = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-ffmpeg"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-ffmpeg"; fi
|
||||
if [ $SRS_TRANSCODE = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-transcode"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-transcode"; fi
|
||||
if [ $SRS_INGEST = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-ingest"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-ingest"; fi
|
||||
if [ $SRS_STAT = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-stat"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-stat"; fi
|
||||
if [ $SRS_HTTP_CALLBACK = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-http-callback"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-http-callback"; fi
|
||||
if [ $SRS_HTTP_SERVER = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-http-server"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-http-server"; fi
|
||||
if [ $SRS_STREAM_CASTER = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-stream-caster"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-stream-caster"; fi
|
||||
if [ $SRS_KAFKA = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-kafka"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-kafka"; fi
|
||||
if [ $SRS_HTTP_API = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-http-api"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-http-api"; fi
|
||||
if [ $SRS_LIBRTMP = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-librtmp"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-librtmp"; fi
|
||||
if [ $SRS_RESEARCH = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-research"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-research"; fi
|
||||
|
@ -638,13 +533,18 @@ SRS_AUTO_CONFIGURE="--prefix=${SRS_PREFIX}"
|
|||
if [ $SRS_GPERF_MP = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-gmp"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-gmp"; fi
|
||||
if [ $SRS_GPERF_CP = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-gcp"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-gcp"; fi
|
||||
if [ $SRS_GPROF = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-gprof"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-gprof"; fi
|
||||
if [ $SRS_ARM_UBUNTU12 = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-arm-ubuntu12"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-arm-ubuntu12"; fi
|
||||
if [ $SRS_MIPS_UBUNTU12 = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --with-mips-ubuntu12"; else SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --without-mips-ubuntu12"; fi
|
||||
if [ $SRS_STATIC = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --static"; fi
|
||||
if [ $SRS_SHARED_ST = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --use-shared-st"; fi
|
||||
if [ $SRS_LOG_VERBOSE = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --log-verbose"; fi
|
||||
if [ $SRS_LOG_INFO = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --log-info"; fi
|
||||
if [ $SRS_LOG_TRACE = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --log-trace"; fi
|
||||
if [ $SRS_GCOV = YES ]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --gcov"; fi
|
||||
if [[ $SRS_EXTRA_FLAGS != '' ]]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --extra-flags=\\\"$SRS_EXTRA_FLAGS\\\""; fi
|
||||
if [[ $SRS_TOOL_CC != '' ]]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --cc=$SRS_TOOL_CC"; fi
|
||||
if [[ $SRS_TOOL_CXX != '' ]]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --cxx=$SRS_TOOL_CXX"; fi
|
||||
if [[ $SRS_TOOL_AR != '' ]]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --ar=$SRS_TOOL_AR"; fi
|
||||
if [[ $SRS_TOOL_LD != '' ]]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --ld=$SRS_TOOL_LD"; fi
|
||||
if [[ $SRS_TOOL_RANDLIB != '' ]]; then SRS_AUTO_CONFIGURE="${SRS_AUTO_CONFIGURE} --randlib=$SRS_TOOL_RANDLIB"; fi
|
||||
echo "User config: $SRS_AUTO_USER_CONFIGURE"
|
||||
echo "Detail config: ${SRS_AUTO_CONFIGURE}"
|
||||
}
|
||||
|
@ -654,6 +554,28 @@ regenerate_options
|
|||
# check user options
|
||||
#####################################################################################
|
||||
function check_option_conflicts() {
|
||||
if [[ $SRS_TOOL_CC == '' || $SRS_TOOL_CXX == '' || $SRS_TOOL_AR == '' || $SRS_TOOL_LD == '' || $SRS_TOOL_RANDLIB == '' ]]; then
|
||||
echo "No crossbuild tools, cc: $SRS_TOOL_CC, cxx: $SRS_TOOL_CXX, ar: $SRS_TOOL_AR, ld: $SRS_TOOL_LD, randlib: $SRS_TOOL_RANDLIB"; exit -1
|
||||
fi
|
||||
|
||||
if [[ $SRS_CROSS_BUILD == YES && ($SRS_TOOL_CC == 'gcc' || $SRS_TOOL_CXX == 'g++' || $SRS_TOOL_AR == 'ar') ]]; then
|
||||
echo "For crossbuild, must not use default toolchain, cc: $SRS_TOOL_CC, cxx: $SRS_TOOL_CXX, ar: $SRS_TOOL_AR"; exit -1
|
||||
fi
|
||||
|
||||
if [ $SRS_OSX = YES ]; then
|
||||
echo "We don't support OSX, please use docker https://github.com/ossrs/srs-docker"; exit -1
|
||||
fi
|
||||
|
||||
if [[ $SRS_NGINX == YES ]]; then
|
||||
echo "Don't support building NGINX, please use docker https://github.com/ossrs/srs-docker"; exit -1
|
||||
fi
|
||||
|
||||
if [[ $SRS_FFMPEG_TOOL == YES ]]; then
|
||||
echo "Don't support building FFMPEG, please use docker https://github.com/ossrs/srs-docker"; exit -1
|
||||
fi
|
||||
|
||||
# TODO: FIXME: check more os.
|
||||
|
||||
__check_ok=YES
|
||||
# check conflict
|
||||
if [ $SRS_GPERF = NO ]; then
|
||||
|
@ -678,42 +600,10 @@ function check_option_conflicts() {
|
|||
echo "gmc/gmp/gcp not compatible with gprof, see: ./configure --help"; __check_ok=NO;
|
||||
fi fi
|
||||
|
||||
# check embeded(arm/mips), if embeded enabled, only allow st/ssl/librtmp,
|
||||
# user should disable all other features
|
||||
if [ $SRS_CROSS_BUILD = YES ]; then
|
||||
if [ $SRS_FFMPEG_TOOL = YES ]; then echo "ffmpeg for arm is not available, see: ./configure --help"; __check_ok=NO; fi
|
||||
if [ $SRS_RESEARCH = YES ]; then echo "research for arm is not available, see: ./configure --help"; __check_ok=NO; fi
|
||||
if [ $SRS_GPERF = YES ]; then echo "gperf for arm is not available, see: ./configure --help"; __check_ok=NO; fi
|
||||
if [ $SRS_GPERF_MC = YES ]; then echo "gmc for arm is not available, see: ./configure --help"; __check_ok=NO; fi
|
||||
if [ $SRS_GPERF_MD = YES ]; then echo "gmd for arm is not available, see: ./configure --help"; __check_ok=NO; fi
|
||||
if [ $SRS_GPERF_MP = YES ]; then echo "gmp for arm is not available, see: ./configure --help"; __check_ok=NO; fi
|
||||
if [ $SRS_GPERF_CP = YES ]; then echo "gcp for arm is not available, see: ./configure --help"; __check_ok=NO; fi
|
||||
if [ $SRS_GPROF = YES ]; then echo "gprof for arm is not available, see: ./configure --help"; __check_ok=NO; fi
|
||||
fi
|
||||
|
||||
# osx not support gperf.
|
||||
if [ $SRS_OSX = YES ]; then
|
||||
if [ $SRS_GPERF = YES ]; then echo "gperf for osx is not available, see: ./configure --help"; __check_ok=NO; fi
|
||||
if [ $SRS_GPERF_MC = YES ]; then echo "gmc for osx is not available, see: ./configure --help"; __check_ok=NO; fi
|
||||
if [ $SRS_GPERF_MD = YES ]; then echo "gmd for osx is not available, see: ./configure --help"; __check_ok=NO; fi
|
||||
if [ $SRS_GPERF_MP = YES ]; then echo "gmp for osx is not available, see: ./configure --help"; __check_ok=NO; fi
|
||||
if [ $SRS_GPERF_CP = YES ]; then echo "gcp for osx is not available, see: ./configure --help"; __check_ok=NO; fi
|
||||
fi
|
||||
|
||||
# if osx, never use static
|
||||
if [[ $SRS_OSX = YES && $SRS_STATIC = YES ]]; then
|
||||
echo "osx should never use static, see: ./configure --help"; __check_ok=NO;
|
||||
fi
|
||||
|
||||
# TODO: FIXME: check more os.
|
||||
|
||||
# check variable neccessary
|
||||
if [ $SRS_HDS = RESERVED ]; then echo "you must specifies the hds, see: ./configure --help"; __check_ok=NO; fi
|
||||
if [ $SRS_NGINX = RESERVED ]; then echo "you must specifies the nginx, see: ./configure --help"; __check_ok=NO; fi
|
||||
if [ $SRS_SSL = RESERVED ]; then echo "you must specifies the ssl, see: ./configure --help"; __check_ok=NO; fi
|
||||
if [ $SRS_FFMPEG_TOOL = RESERVED ]; then echo "you must specifies the ffmpeg, see: ./configure --help"; __check_ok=NO; fi
|
||||
if [ $SRS_STREAM_CASTER = RESERVED ]; then echo "you must specifies the stream-caster, see: ./configure --help"; __check_ok=NO; fi
|
||||
if [ $SRS_KAFKA = RESERVED ]; then echo "you must specifies the kafka, see: ./configure --help"; __check_ok=NO; fi
|
||||
if [ $SRS_LIBRTMP = RESERVED ]; then echo "you must specifies the librtmp, see: ./configure --help"; __check_ok=NO; fi
|
||||
if [ $SRS_RESEARCH = RESERVED ]; then echo "you must specifies the research, see: ./configure --help"; __check_ok=NO; fi
|
||||
if [ $SRS_UTEST = RESERVED ]; then echo "you must specifies the utest, see: ./configure --help"; __check_ok=NO; fi
|
||||
|
@ -723,21 +613,9 @@ function check_option_conflicts() {
|
|||
if [ $SRS_GPERF_MP = RESERVED ]; then echo "you must specifies the gperf-mp, see: ./configure --help"; __check_ok=NO; fi
|
||||
if [ $SRS_GPERF_CP = RESERVED ]; then echo "you must specifies the gperf-cp, see: ./configure --help"; __check_ok=NO; fi
|
||||
if [ $SRS_GPROF = RESERVED ]; then echo "you must specifies the gprof, see: ./configure --help"; __check_ok=NO; fi
|
||||
if [ $SRS_ARM_UBUNTU12 = RESERVED ]; then echo "you must specifies the arm-ubuntu12, see: ./configure --help"; __check_ok=NO; fi
|
||||
if [ $SRS_MIPS_UBUNTU12 = RESERVED ]; then echo "you must specifies the mips-ubuntu12, see: ./configure --help"; __check_ok=NO; fi
|
||||
if [[ -z $SRS_PREFIX ]]; then echo "you must specifies the prefix, see: ./configure --prefix"; __check_ok=NO; fi
|
||||
if [ $__check_ok = NO ]; then
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
if [[ $SRS_OSX == YES && $SRS_ALLOW_OSX == NO ]]; then
|
||||
macOSVersion=`sw_vers -productVersion`
|
||||
macOSVersionMajor=`echo $macOSVersion|awk -F '.' '{print $1}'`
|
||||
macOSVersionMinor=`echo $macOSVersion|awk -F '.' '{print $2}'`
|
||||
if [[ $macOSVersionMajor -ge 10 && $macOSVersionMinor -ge 14 ]]; then
|
||||
echo "macOS $macOSVersion is not supported, read https://github.com/ossrs/srs/issues/1250"
|
||||
exit -1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
check_option_conflicts
|
||||
|
|
|
@ -1,30 +1,3 @@
|
|||
#!/bin/bash
|
||||
|
||||
# when options parsed, setup some variables, then build the depends.
|
||||
|
||||
# when arm specified, setup the cross build variables.
|
||||
if [ $SRS_ARM_UBUNTU12 = YES ]; then
|
||||
__SrsArmCC="arm-linux-gnueabi-gcc";
|
||||
__SrsArmGCC="arm-linux-gnueabi-gcc";
|
||||
__SrsArmCXX="arm-linux-gnueabi-g++";
|
||||
__SrsArmAR="arm-linux-gnueabi-ar";
|
||||
__SrsArmLD="arm-linux-gnueabi-ld";
|
||||
__SrsArmRANDLIB="arm-linux-gnueabi-ranlib";
|
||||
fi
|
||||
|
||||
if [ $SRS_MIPS_UBUNTU12 = YES ]; then
|
||||
__SrsArmCC="mipsel-openwrt-linux-gcc";
|
||||
__SrsArmGCC="mipsel-openwrt-linux-gcc";
|
||||
__SrsArmCXX="mipsel-openwrt-linux-g++";
|
||||
__SrsArmAR="mipsel-openwrt-linux-ar";
|
||||
__SrsArmLD="mipsel-openwrt-linux-ld";
|
||||
__SrsArmRANDLIB="mipsel-openwrt-linux-ranlib";
|
||||
fi
|
||||
|
||||
# the arm-ubuntu12 options for make for depends
|
||||
if [[ -z $SrsArmCC ]]; then SrsArmCC=$__SrsArmCC; fi
|
||||
if [[ -z $SrsArmGCC ]]; then SrsArmGCC=$__SrsArmGCC; fi
|
||||
if [[ -z $SrsArmCXX ]]; then SrsArmCXX=$__SrsArmCXX; fi
|
||||
if [[ -z $SrsArmAR ]]; then SrsArmAR=$__SrsArmAR; fi
|
||||
if [[ -z $SrsArmLD ]]; then SrsArmLD=$__SrsArmLD; fi
|
||||
if [[ -z $SrsArmRANDLIB ]]; then SrsArmRANDLIB=$__SrsArmRANDLIB; fi
|
||||
|
|
|
@ -12,7 +12,6 @@ SrsHttpCallbackSummaryColor="\${YELLOW}(Disabled) "; if [ $SRS_HTTP_CALLBACK = Y
|
|||
SrsHttpServerSummaryColor="\${YELLOW}(Disabled) "; if [ $SRS_HTTP_SERVER = YES ]; then SrsHttpServerSummaryColor="\${GREEN}"; fi
|
||||
SrsHttpApiSummaryColor="\${YELLOW}(Disabled) "; if [ $SRS_HTTP_API = YES ]; then SrsHttpApiSummaryColor="\${GREEN}"; fi
|
||||
SrsStreamCasterSummaryColor="\${YELLOW}(Disabled) "; if [ $SRS_STREAM_CASTER = YES ]; then SrsStreamCasterSummaryColor="\${GREEN}"; fi
|
||||
SrsKafkaSummaryColor="\${YELLOW}(Disabled) "; if [ $SRS_KAFKA = YES ]; then SrsKafkaSummaryColor="\${GREEN}"; fi
|
||||
SrsLibrtmpSummaryColor="\${YELLOW}(Disabled) "; if [ $SRS_LIBRTMP = YES ]; then SrsLibrtmpSummaryColor="\${GREEN}"; fi
|
||||
SrsLibrtmpSSLSummaryColor="\${YELLOW}(Disabled) "; if [ $SRS_LIBRTMP = YES ]; then if [ $SRS_SSL = YES ]; then SrsLibrtmpSSLSummaryColor="\${GREEN}"; fi fi
|
||||
SrsResearchSummaryColor="\${GREEN}(Disabled) "; if [ $SRS_RESEARCH = YES ]; then SrsResearchSummaryColor="\${GREEN}"; fi
|
||||
|
@ -44,16 +43,13 @@ echo -e " \${BLACK}+--------------------------------------------------------
|
|||
echo -e " |\${GREEN}The main server usage: ./objs/srs -c conf/srs.conf, start the srs server\${BLACK}"
|
||||
echo -e " | ${SrsHlsSummaryColor}About HLS, please read https://github.com/ossrs/srs/wiki/v2_CN_DeliveryHLS\${BLACK}"
|
||||
echo -e " | ${SrsDvrSummaryColor}About DVR, please read https://github.com/ossrs/srs/wiki/v3_CN_DVR\${BLACK}"
|
||||
echo -e " | ${SrsNginxSummaryColor}About NGINX, please read https://github.com/ossrs/srs/wiki/v2_CN_DeliveryHLS\${BLACK}"
|
||||
echo -e " | ${SrsSslSummaryColor}About SSL, please read https://github.com/ossrs/srs/wiki/v1_CN_RTMPHandshake\${BLACK}"
|
||||
echo -e " | ${SrsFfmpegSummaryColor}About FFMPEG, please read https://github.com/ossrs/srs/wiki/v3_CN_FFMPEG\${BLACK}"
|
||||
echo -e " | ${SrsTranscodeSummaryColor}About transcoding, please read https://github.com/ossrs/srs/wiki/v3_CN_FFMPEG\${BLACK}"
|
||||
echo -e " | ${SrsIngestSummaryColor}About ingester, please read https://github.com/ossrs/srs/wiki/v1_CN_Ingest\${BLACK}"
|
||||
echo -e " | ${SrsHttpCallbackSummaryColor}About http-callback, please read https://github.com/ossrs/srs/wiki/v3_CN_HTTPCallback\${BLACK}"
|
||||
echo -e " | ${SrsHttpServerSummaryColor}Aoubt embeded http-server, please read https://github.com/ossrs/srs/wiki/v2_CN_HTTPServer\${BLACK}"
|
||||
echo -e " | ${SrsHttpServerSummaryColor}Aoubt http-server, please read https://github.com/ossrs/srs/wiki/v2_CN_HTTPServer\${BLACK}"
|
||||
echo -e " | ${SrsHttpApiSummaryColor}About http-api, please read https://github.com/ossrs/srs/wiki/v3_CN_HTTPApi\${BLACK}"
|
||||
echo -e " | ${SrsStreamCasterSummaryColor}About stream-caster, please read https://github.com/ossrs/srs/wiki/v2_CN_Streamer\${BLACK}"
|
||||
echo -e " | ${SrsKafkaSummaryColor}About kafka, please read https://github.com/ossrs/srs/wiki/v3_CN_Kafka\${BLACK}"
|
||||
echo -e " | ${SrsValgrindSummaryColor}About VALGRIND, please read https://github.com/ossrs/state-threads/issues/2\${BLACK}"
|
||||
echo -e " \${BLACK}+------------------------------------------------------------------------------------\${BLACK}"
|
||||
echo -e "\${GREEN}binaries, please read https://github.com/ossrs/srs/wiki/v2_CN_Build\${BLACK}"
|
||||
|
|
|
@ -23,12 +23,6 @@ GTEST_DIR=${SRS_TRUNK_PREFIX}/${SRS_OBJS_DIR}/gtest
|
|||
# the extra defines to compile utest.
|
||||
EXTRA_DEFINES=""
|
||||
|
||||
# for osx to disable the error.
|
||||
# gtest/include/gtest/internal/gtest-port.h:499:13: fatal error: 'tr1/tuple' file not found
|
||||
if [ $SRS_OSX = YES ]; then
|
||||
EXTRA_DEFINES="$EXTRA_DEFINES -DGTEST_HAS_TR1_TUPLE=0"
|
||||
fi
|
||||
|
||||
cat << END > ${FILE}
|
||||
# user must run make the ${SRS_OBJS_DIR}/utest dir
|
||||
# at the same dir of Makefile.
|
||||
|
@ -173,7 +167,11 @@ echo "" >> ${FILE}
|
|||
echo "# link all depends libraries" >> ${FILE}
|
||||
echo -n "DEPS_LIBRARIES_FILES = " >> ${FILE}
|
||||
for item in ${ModuleLibFiles[*]}; do
|
||||
echo -n "${SRS_TRUNK_PREFIX}/${item} " >> ${FILE}
|
||||
if [[ -f ${item} ]]; then
|
||||
echo -n "${SRS_TRUNK_PREFIX}/${item} " >> ${FILE}
|
||||
else
|
||||
echo -n "${item} " >> ${FILE}
|
||||
fi
|
||||
done
|
||||
echo "" >> ${FILE}; echo "" >> ${FILE}
|
||||
#
|
||||
|
|
23
trunk/conf/dash.conf
Normal file
23
trunk/conf/dash.conf
Normal file
|
@ -0,0 +1,23 @@
|
|||
# the config for srs to delivery dash
|
||||
# @see https://github.com/ossrs/srs/wiki/v1_CN_SampleDASH
|
||||
# @see full.conf for detail config.
|
||||
|
||||
listen 1935;
|
||||
max_connections 1000;
|
||||
daemon off;
|
||||
srs_log_tank console;
|
||||
http_server {
|
||||
enabled on;
|
||||
listen 8080;
|
||||
dir ./objs/nginx/html;
|
||||
}
|
||||
vhost __defaultVhost__ {
|
||||
dash {
|
||||
enabled on;
|
||||
dash_fragment 30;
|
||||
dash_update_period 150;
|
||||
dash_timeshift 300;
|
||||
dash_path ./objs/nginx/html;
|
||||
dash_mpd_file [app]/[stream].mpd;
|
||||
}
|
||||
}
|
15
trunk/conf/edge2.conf
Normal file
15
trunk/conf/edge2.conf
Normal file
|
@ -0,0 +1,15 @@
|
|||
# the config for srs origin-edge cluster
|
||||
# @see https://github.com/ossrs/srs/wiki/v1_CN_Edge
|
||||
# @see full.conf for detail config.
|
||||
|
||||
listen 1935;
|
||||
max_connections 1000;
|
||||
pid objs/edge2.pid;
|
||||
daemon off;
|
||||
srs_log_tank console;
|
||||
vhost __defaultVhost__ {
|
||||
cluster {
|
||||
mode remote;
|
||||
origin 127.0.0.1:19350;
|
||||
}
|
||||
}
|
|
@ -19,11 +19,16 @@ pid ./objs/srs.pid;
|
|||
# performance about 10%.
|
||||
# default: 60000
|
||||
chunk_size 60000;
|
||||
# the logs dir.
|
||||
# the log dir for FFMPEG.
|
||||
# if enabled ffmpeg, each transcoding stream will create a log file.
|
||||
# /dev/null to disable the log.
|
||||
# default: ./objs
|
||||
ff_log_dir ./objs;
|
||||
# the log level for FFMPEG.
|
||||
# info warning error fatal panic quiet
|
||||
# trace debug verbose
|
||||
# default: info
|
||||
ff_log_level info;
|
||||
# the log tank, console or file.
|
||||
# if console, print log to console.
|
||||
# if file, write log to file. requires srs_log_file if log to file.
|
||||
|
@ -67,6 +72,38 @@ work_dir ./;
|
|||
# @reamrk do not support reload.
|
||||
# default: off
|
||||
asprocess off;
|
||||
# Whether client empty IP is ok, for example, health checking by SLB.
|
||||
# If ok(on), we will ignore this connection without warnings or errors.
|
||||
# default: on
|
||||
empty_ip_ok on;
|
||||
|
||||
# For gracefully quit, wait for a while then close listeners,
|
||||
# because K8S notify SRS with SIGQUIT and update Service simultaneously,
|
||||
# maybe there is some new connections incoming before Service updated.
|
||||
# @see https://github.com/ossrs/srs/issues/1595#issuecomment-587516567
|
||||
# default: 2300
|
||||
grace_start_wait 2300;
|
||||
# For gracefully quit, final wait for cleanup in milliseconds.
|
||||
# @see https://github.com/ossrs/srs/issues/1579#issuecomment-587414898
|
||||
# default: 3200
|
||||
grace_final_wait 3200;
|
||||
# Whether force gracefully quit, never fast quit.
|
||||
# By default, SIGTERM which means fast quit, is sent by K8S, so we need to
|
||||
# force SRS to treat SIGTERM as gracefully quit for gray release or canary.
|
||||
# @see https://github.com/ossrs/srs/issues/1579#issuecomment-587475077
|
||||
# default: off
|
||||
force_grace_quit off;
|
||||
# Whether disable daemon for docker.
|
||||
# If on, it will set daemon to off in docker, even daemon is on.
|
||||
# default: on
|
||||
disable_daemon_for_docker on;
|
||||
# Whether auto reload by watching the config file by inotify.
|
||||
# default: off
|
||||
inotify_auto_reload off;
|
||||
# Whether enable inotify_auto_reload for docker.
|
||||
# If on, it will set inotify_auto_reload to on in docker, even it's off.
|
||||
# default: on
|
||||
auto_reload_for_docker on;
|
||||
|
||||
#############################################################################################
|
||||
# heartbeat/stats sections
|
||||
|
@ -196,7 +233,7 @@ stream_caster {
|
|||
# the caster type of stream, the casters:
|
||||
# mpegts_over_udp, MPEG-TS over UDP caster.
|
||||
# rtsp, Real Time Streaming Protocol (RTSP).
|
||||
# flv, FLV over HTTP POST.
|
||||
# flv, FLV over HTTP by POST.
|
||||
caster mpegts_over_udp;
|
||||
# the output rtmp url.
|
||||
# for mpegts_over_udp caster, the typically output url:
|
||||
|
@ -247,25 +284,6 @@ stream_caster {
|
|||
listen 8936;
|
||||
}
|
||||
|
||||
#############################################################################################
|
||||
# Kafka sections
|
||||
#############################################################################################
|
||||
# Apache Kafka is a high-throughput distributed messaging system.
|
||||
# SRS is a Kafka producer to send message to kafka.
|
||||
# @see https://kafka.apache.org/documentation.html#introduction
|
||||
kafka {
|
||||
# whether enabled kafka.
|
||||
# default: off
|
||||
enabled off;
|
||||
# the broker list, broker is <ip:port>
|
||||
# and use space to specify multple brokers.
|
||||
# for example, 127.0.0.1:9092 127.0.0.1:9093
|
||||
brokers 127.0.0.1:9092;
|
||||
# the kafka topic to use.
|
||||
# default: srs
|
||||
topic srs;
|
||||
}
|
||||
|
||||
#############################################################################################
|
||||
# RTMP/HTTP VHOST sections
|
||||
#############################################################################################
|
||||
|
@ -665,7 +683,7 @@ vhost refer.anti_suck.com {
|
|||
}
|
||||
}
|
||||
|
||||
# vhost for bandwidth check
|
||||
# vhost for bwt(bandwidth check)
|
||||
# generally, the bandcheck vhost must be: bandcheck.srs.com,
|
||||
# or need to modify the vhost of client.
|
||||
vhost bandcheck.srs.com {
|
||||
|
@ -952,6 +970,16 @@ vhost exec.srs.com {
|
|||
# [tcUrl] the client request tcUrl.
|
||||
# [swfUrl] the client request swfUrl.
|
||||
# [pageUrl] the client request pageUrl.
|
||||
# we also support datetime variables.
|
||||
# [2006], replace this const to current year.
|
||||
# [01], replace this const to current month.
|
||||
# [02], replace this const to current date.
|
||||
# [15], replace this const to current hour.
|
||||
# [04], replace this const to current minute.
|
||||
# [05], replace this const to current second.
|
||||
# [999], replace this const to current millisecond.
|
||||
# [timestamp],replace this const to current UNIX timestamp in ms.
|
||||
# @remark we use golang time format "2006-01-02 15:04:05.999" as "[2006]-[01]-[02]_[15].[04].[05]_[999]"
|
||||
# @remark empty to ignore this exec.
|
||||
publish ./objs/ffmpeg/bin/ffmpeg -f flv -i [url] -c copy -y ./[stream].flv;
|
||||
}
|
||||
|
@ -965,14 +993,14 @@ vhost dash.srs.com {
|
|||
# Default: off
|
||||
enabled on;
|
||||
# The duration of segment in seconds.
|
||||
# Default: 3
|
||||
dash_fragment 3;
|
||||
# The period to update the MPD in seconds.
|
||||
# Default: 30
|
||||
dash_update_period 30;
|
||||
dash_fragment 30;
|
||||
# The period to update the MPD in seconds.
|
||||
# Default: 150
|
||||
dash_update_period 150;
|
||||
# The depth of timeshift buffer in seconds.
|
||||
# Default: 60
|
||||
dash_timeshift 60;
|
||||
# Default: 300
|
||||
dash_timeshift 300;
|
||||
# The base/home dir/path for dash.
|
||||
# All init and segment files will write under this dir.
|
||||
dash_path ./objs/nginx/html;
|
||||
|
@ -1084,9 +1112,8 @@ vhost hls.srs.com {
|
|||
# whether cleanup the old expired ts files.
|
||||
# default: on
|
||||
hls_cleanup on;
|
||||
# the timeout in seconds to dispose the hls,
|
||||
# dispose is to remove all hls files, m3u8 and ts files.
|
||||
# when publisher timeout dispose hls.
|
||||
# If there is no incoming packets, dispose HLS in this timeout in seconds,
|
||||
# which removes all HLS files including m3u8 and ts files.
|
||||
# @remark 0 to disable dispose for publisher.
|
||||
# @remark apply for publisher timeout only, while "etc/init.d/srs stop" always dispose hls.
|
||||
# default: 0
|
||||
|
@ -1123,6 +1150,15 @@ vhost hls.srs.com {
|
|||
# @remark It's optional.
|
||||
hls_key_url https://localhost:8080;
|
||||
|
||||
# Special control controls.
|
||||
###########################################
|
||||
# Whether calculate the DTS of audio frame directly.
|
||||
# If on, guess the specific DTS by AAC samples, please read https://github.com/ossrs/srs/issues/547#issuecomment-294350544
|
||||
# If off, directly turn the FLV timestamp to DTS, which might cause corrupt audio stream.
|
||||
# @remark Recommend to set to off, unless your audio stream sample-rate and timestamp is not correct.
|
||||
# Default: on
|
||||
hls_dts_directly on;
|
||||
|
||||
# on_hls, never config in here, should config in http_hooks.
|
||||
# for the hls http callback, @see http_hooks.on_hls of vhost hooks.callback.srs.com
|
||||
# @read https://github.com/ossrs/srs/wiki/v2_CN_DeliveryHLS#http-callback
|
||||
|
@ -1297,6 +1333,16 @@ vhost ingest.srs.com {
|
|||
# output stream. variables:
|
||||
# [vhost] current vhost which start the ingest.
|
||||
# [port] system RTMP stream port.
|
||||
# we also support datetime variables.
|
||||
# [2006], replace this const to current year.
|
||||
# [01], replace this const to current month.
|
||||
# [02], replace this const to current date.
|
||||
# [15], replace this const to current hour.
|
||||
# [04], replace this const to current minute.
|
||||
# [05], replace this const to current second.
|
||||
# [999], replace this const to current millisecond.
|
||||
# [timestamp],replace this const to current UNIX timestamp in ms.
|
||||
# @remark we use golang time format "2006-01-02 15:04:05.999" as "[2006]-[01]-[02]_[15].[04].[05]_[999]"
|
||||
output rtmp://127.0.0.1:[port]/live?vhost=[vhost]/livestream;
|
||||
}
|
||||
}
|
||||
|
@ -1485,6 +1531,16 @@ vhost example.transcode.srs.com {
|
|||
# [app] the input stream app.
|
||||
# [stream] the input stream name.
|
||||
# [engine] the transcode engine name.
|
||||
# we also support datetime variables.
|
||||
# [2006], replace this const to current year.
|
||||
# [01], replace this const to current month.
|
||||
# [02], replace this const to current date.
|
||||
# [15], replace this const to current hour.
|
||||
# [04], replace this const to current minute.
|
||||
# [05], replace this const to current second.
|
||||
# [999], replace this const to current millisecond.
|
||||
# [timestamp],replace this const to current UNIX timestamp in ms.
|
||||
# @remark we use golang time format "2006-01-02 15:04:05.999" as "[2006]-[01]-[02]_[15].[04].[05]_[999]"
|
||||
output rtmp://127.0.0.1:[port]/[app]?vhost=[vhost]/[stream]_[engine];
|
||||
}
|
||||
}
|
||||
|
|
15
trunk/conf/go-oryx-edge.conf
Normal file
15
trunk/conf/go-oryx-edge.conf
Normal file
|
@ -0,0 +1,15 @@
|
|||
# the config for srs origin-edge cluster
|
||||
# @see https://github.com/ossrs/srs/wiki/v1_CN_Edge
|
||||
# @see full.conf for detail config.
|
||||
|
||||
listen 19351;
|
||||
max_connections 1000;
|
||||
pid objs/edge1.pid;
|
||||
daemon off;
|
||||
srs_log_tank console;
|
||||
vhost __defaultVhost__ {
|
||||
cluster {
|
||||
mode remote;
|
||||
origin 127.0.0.1:19350;
|
||||
}
|
||||
}
|
15
trunk/conf/go-oryx-edge2.conf
Normal file
15
trunk/conf/go-oryx-edge2.conf
Normal file
|
@ -0,0 +1,15 @@
|
|||
# the config for srs origin-edge cluster
|
||||
# @see https://github.com/ossrs/srs/wiki/v1_CN_Edge
|
||||
# @see full.conf for detail config.
|
||||
|
||||
listen 19352;
|
||||
max_connections 1000;
|
||||
pid objs/edge2.pid;
|
||||
daemon off;
|
||||
srs_log_tank console;
|
||||
vhost __defaultVhost__ {
|
||||
cluster {
|
||||
mode remote;
|
||||
origin 127.0.0.1:19350;
|
||||
}
|
||||
}
|
|
@ -6,6 +6,11 @@ listen 1935;
|
|||
max_connections 1000;
|
||||
daemon off;
|
||||
srs_log_tank console;
|
||||
http_server {
|
||||
enabled on;
|
||||
listen 8080;
|
||||
dir ./objs/nginx/html;
|
||||
}
|
||||
vhost __defaultVhost__ {
|
||||
hls {
|
||||
enabled on;
|
||||
|
|
|
@ -15,6 +15,6 @@ vhost __defaultVhost__ {
|
|||
cluster {
|
||||
mode local;
|
||||
origin_cluster on;
|
||||
coworkers 127.0.0.1:9091;
|
||||
coworkers 127.0.0.1:9090 127.0.0.1:9091 127.0.0.1:9092;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,6 @@ vhost __defaultVhost__ {
|
|||
cluster {
|
||||
mode local;
|
||||
origin_cluster on;
|
||||
coworkers 127.0.0.1:9090;
|
||||
coworkers 127.0.0.1:9090 127.0.0.1:9091 127.0.0.1:9092;
|
||||
}
|
||||
}
|
||||
|
|
20
trunk/conf/origin.cluster.serverC.conf
Normal file
20
trunk/conf/origin.cluster.serverC.conf
Normal file
|
@ -0,0 +1,20 @@
|
|||
# the config for srs origin-origin cluster
|
||||
# @see https://github.com/ossrs/srs/wiki/v3_EN_OriginCluster
|
||||
# @see full.conf for detail config.
|
||||
|
||||
listen 19352;
|
||||
max_connections 1000;
|
||||
daemon off;
|
||||
srs_log_tank console;
|
||||
pid ./objs/origin.cluster.serverC.pid;
|
||||
http_api {
|
||||
enabled on;
|
||||
listen 9092;
|
||||
}
|
||||
vhost __defaultVhost__ {
|
||||
cluster {
|
||||
mode local;
|
||||
origin_cluster on;
|
||||
coworkers 127.0.0.1:9090 127.0.0.1:9091 127.0.0.1:9092;
|
||||
}
|
||||
}
|
114
trunk/configure
vendored
114
trunk/configure
vendored
|
@ -17,7 +17,7 @@ BLACK="\\033[0m"
|
|||
|
||||
#####################################################################################
|
||||
# parse user options, set the variables like:
|
||||
# srs features: SRS_SSL/SRS_HLS/SRS_NGINX/SRS_FFMPEG_TOOL/SRS_HTTP_CALLBACK/......
|
||||
# srs features: SRS_SSL/SRS_HLS/SRS_HTTP_CALLBACK/......
|
||||
# build options: SRS_JOBS
|
||||
#####################################################################################
|
||||
# parse options, exit with error when parse options invalid.
|
||||
|
@ -83,6 +83,13 @@ for SRS_MODULE in ${SRS_MODULES[*]}; do
|
|||
fi
|
||||
done
|
||||
|
||||
# generate extra phony for each modules.
|
||||
cat << END > ${SRS_OBJS}/${SRS_MAKEFILE}
|
||||
|
||||
.PHONY: $__mphonys
|
||||
|
||||
END
|
||||
|
||||
#####################################################################################
|
||||
# build tools or compiler args.
|
||||
# enable gdb debug
|
||||
|
@ -111,13 +118,17 @@ fi
|
|||
if [[ $SRS_GCOV == YES ]]; then
|
||||
CXXFLAGS="${CXXFLAGS} ${SrsGcov}";
|
||||
fi
|
||||
# User configed options.
|
||||
if [[ $SRS_EXTRA_FLAGS != '' ]]; then
|
||||
CXXFLAGS="${CXXFLAGS} $SRS_EXTRA_FLAGS";
|
||||
fi
|
||||
# Start to generate the Makefile.
|
||||
cat << END > ${SRS_OBJS}/${SRS_MAKEFILE}
|
||||
GCC = gcc
|
||||
CXX = g++
|
||||
AR = ar
|
||||
cat << END >> ${SRS_OBJS}/${SRS_MAKEFILE}
|
||||
GCC = ${SRS_TOOL_CC}
|
||||
CXX = ${SRS_TOOL_CXX}
|
||||
AR = ${SRS_TOOL_AR}
|
||||
ARFLAGS = -rs
|
||||
LINK = g++
|
||||
LINK = ${SRS_TOOL_CXX}
|
||||
CXXFLAGS = ${CXXFLAGS}
|
||||
|
||||
.PHONY: default srs srs_ingest_hls librtmp
|
||||
|
@ -133,6 +144,7 @@ END
|
|||
#
|
||||
# st(state-threads) the basic network library for SRS.
|
||||
LibSTRoot="${SRS_OBJS_DIR}/st"; LibSTfile="${LibSTRoot}/libst.a"
|
||||
if [[ $SRS_SHARED_ST == YES ]]; then LibSTfile="-lst"; fi
|
||||
# openssl-1.1.0e, for the RTMP complex handshake.
|
||||
LibSSLRoot="";LibSSLfile=""
|
||||
if [[ $SRS_SSL == YES && $SRS_USE_SYS_SSL == NO ]]; then
|
||||
|
@ -156,10 +168,6 @@ fi
|
|||
if [ $SRS_STATIC = YES ]; then
|
||||
SrsLinkOptions="${SrsLinkOptions} -static";
|
||||
fi
|
||||
# if mips, add -lgcc_eh, or stl compile failed.
|
||||
if [ $SRS_MIPS_UBUNTU12 = YES ]; then
|
||||
SrsLinkOptions="${SrsLinkOptions} -lgcc_eh";
|
||||
fi
|
||||
# For coverage.
|
||||
if [[ $SRS_GCOV == YES ]]; then
|
||||
SrsLinkOptions="${SrsLinkOptions} ${SrsGcov}";
|
||||
|
@ -172,7 +180,7 @@ fi
|
|||
MODULE_ID="CORE"
|
||||
MODULE_DEPENDS=()
|
||||
ModuleLibIncs=(${SRS_OBJS_DIR})
|
||||
MODULE_FILES=("srs_core" "srs_core_autofree" "srs_core_performance"
|
||||
MODULE_FILES=("srs_core" "srs_core_version3" "srs_core_autofree" "srs_core_performance"
|
||||
"srs_core_mem_watch" "srs_core_time")
|
||||
CORE_INCS="src/core"; MODULE_DIR=${CORE_INCS} . auto/modules.sh
|
||||
CORE_OBJS="${MODULE_OBJS[@]}"
|
||||
|
@ -195,7 +203,7 @@ ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSSLRoot})
|
|||
MODULE_FILES=("srs_protocol_amf0" "srs_protocol_io" "srs_rtmp_stack"
|
||||
"srs_rtmp_handshake" "srs_protocol_utility" "srs_rtmp_msg_array" "srs_protocol_stream"
|
||||
"srs_raw_avc" "srs_rtsp_stack" "srs_http_stack" "srs_protocol_kbps" "srs_protocol_json"
|
||||
"srs_kafka_stack" "srs_protocol_format")
|
||||
"srs_protocol_format")
|
||||
PROTOCOL_INCS="src/protocol"; MODULE_DIR=${PROTOCOL_INCS} . auto/modules.sh
|
||||
PROTOCOL_OBJS="${MODULE_OBJS[@]}"
|
||||
#
|
||||
|
@ -225,7 +233,7 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
|||
"srs_app_heartbeat" "srs_app_empty" "srs_app_http_client" "srs_app_http_static"
|
||||
"srs_app_recv_thread" "srs_app_security" "srs_app_statistic" "srs_app_hds"
|
||||
"srs_app_mpegts_udp" "srs_app_rtsp" "srs_app_listener" "srs_app_async_call"
|
||||
"srs_app_caster_flv" "srs_app_process" "srs_app_ng_exec" "srs_app_kafka"
|
||||
"srs_app_caster_flv" "srs_app_process" "srs_app_ng_exec"
|
||||
"srs_app_hourglass" "srs_app_dash" "srs_app_fragment" "srs_app_dvr"
|
||||
"srs_app_coworkers")
|
||||
DEFINES=""
|
||||
|
@ -314,9 +322,9 @@ fi
|
|||
#
|
||||
# utest, the unit-test cases of srs, base on gtest1.6
|
||||
if [ $SRS_UTEST = YES ]; then
|
||||
MODULE_FILES=("srs_utest" "srs_utest_amf0" "srs_utest_protocol"
|
||||
"srs_utest_kernel" "srs_utest_core" "srs_utest_config"
|
||||
"srs_utest_reload" "srs_utest_service" "srs_utest_app")
|
||||
MODULE_FILES=("srs_utest" "srs_utest_amf0" "srs_utest_protocol" "srs_utest_kernel" "srs_utest_core"
|
||||
"srs_utest_config" "srs_utest_rtmp" "srs_utest_http" "srs_utest_avc" "srs_utest_reload"
|
||||
"srs_utest_mp4" "srs_utest_service" "srs_utest_app")
|
||||
ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSTRoot} ${LibSSLRoot})
|
||||
ModuleLibFiles=(${LibSTfile} ${LibSSLfile})
|
||||
MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL" "SERVICE" "APP")
|
||||
|
@ -344,23 +352,10 @@ cat << END > ${SRS_WORKDIR}/${SRS_MAKEFILE}
|
|||
SRS_PREFIX=${SRS_PREFIX}
|
||||
__REAL_INSTALL=\$(DESTDIR)\$(SRS_PREFIX)
|
||||
|
||||
END
|
||||
|
||||
# embeded, ubuntu12, use embeded tool chain.
|
||||
if [ $SRS_CROSS_BUILD = YES ]; then
|
||||
cat << END >> ${SRS_WORKDIR}/${SRS_MAKEFILE}
|
||||
default:
|
||||
\$(MAKE) GCC=${SrsArmGCC} CXX=${SrsArmCXX} AR=${SrsArmAR} LINK=${SrsArmCXX} _default
|
||||
|
||||
END
|
||||
# x86/x64, use gnu-gcc/g++ tool chain.
|
||||
else
|
||||
cat << END >> ${SRS_WORKDIR}/${SRS_MAKEFILE}
|
||||
default:
|
||||
\$(MAKE) _default
|
||||
|
||||
END
|
||||
fi
|
||||
|
||||
# the real entry for all platform:
|
||||
# the server, librtmp and utest
|
||||
|
@ -422,13 +417,13 @@ for SRS_MODULE in ${SRS_MODULES[*]}; do
|
|||
# if export librtmp, donot build the bravo-ingest.
|
||||
if [ $SRS_EXPORT_LIBRTMP_PROJECT != NO ]; then
|
||||
cat << END >> ${SRS_WORKDIR}/${SRS_MAKEFILE}
|
||||
$SRS_MODULE_NAME: _prepare_dir
|
||||
$SRS_MODULE_NAME: _prepare_dir server
|
||||
@echo "Ingore the $SRS_MODULE_NAME for srs-librtmp"
|
||||
|
||||
END
|
||||
else
|
||||
cat << END >> ${SRS_WORKDIR}/${SRS_MAKEFILE}
|
||||
$SRS_MODULE_NAME: _prepare_dir
|
||||
$SRS_MODULE_NAME: _prepare_dir server
|
||||
@echo "Build the $SRS_MODULE_NAME over SRS"
|
||||
\$(MAKE) -f ${SRS_OBJS_DIR}/${SRS_MAKEFILE} $SRS_MODULE_NAME
|
||||
|
||||
|
@ -484,22 +479,30 @@ install:
|
|||
@mkdir -p \$(__REAL_INSTALL)
|
||||
@echo "Now make the http root dir"
|
||||
@mkdir -p \$(__REAL_INSTALL)/objs/nginx/html
|
||||
@cp research/api-server/static-dir/crossdomain.xml \$(__REAL_INSTALL)/objs/nginx/html
|
||||
@cp -f research/api-server/static-dir/crossdomain.xml \$(__REAL_INSTALL)/objs/nginx/html
|
||||
@echo "Now copy binary files"
|
||||
@mkdir -p \$(__REAL_INSTALL)/objs
|
||||
@cp objs/srs \$(__REAL_INSTALL)/objs
|
||||
@cp -f objs/srs \$(__REAL_INSTALL)/objs
|
||||
@echo "Now copy srs conf files"
|
||||
@mkdir -p \$(__REAL_INSTALL)/conf
|
||||
@cp conf/*.conf \$(__REAL_INSTALL)/conf
|
||||
@cp -f conf/*.conf \$(__REAL_INSTALL)/conf
|
||||
@echo "Now copy init.d script files"
|
||||
@mkdir -p \$(__REAL_INSTALL)/etc/init.d
|
||||
@cp etc/init.d/srs \$(__REAL_INSTALL)/etc/init.d
|
||||
@cp -f etc/init.d/srs \$(__REAL_INSTALL)/etc/init.d
|
||||
@sed -i "s|^ROOT=.*|ROOT=\"\$(SRS_PREFIX)\"|g" \$(__REAL_INSTALL)/etc/init.d/srs
|
||||
@echo "Now copy systemctl service files"
|
||||
@mkdir -p \$(__REAL_INSTALL)/usr/lib/systemd/system
|
||||
@cp -f usr/lib/systemd/system/srs.service \$(__REAL_INSTALL)/usr/lib/systemd/system/srs.service
|
||||
@echo ""
|
||||
@echo "SRS is installed, to link and start srs:"
|
||||
@echo " sudo ln -sf \$(SRS_PREFIX)/etc/init.d/srs /etc/init.d/srs"
|
||||
@echo "The api installed, to link and start srs, please"
|
||||
@echo "For CentOS6:"
|
||||
@echo " sudo ln -sf \$(SRS_PREFIX)/etc/init.d/srs /etc/init.d/srs &&"
|
||||
@echo " /etc/init.d/srs start"
|
||||
@echo "@see: https://github.com/ossrs/srs/wiki/v1_CN_LinuxService"
|
||||
@echo "For CentOS7:"
|
||||
@echo " sudo ln -sf \$(SRS_PREFIX)/etc/init.d/srs /etc/init.d/srs &&"
|
||||
@echo " sudo cp -f \$(SRS_PREFIX)/usr/lib/systemd/system/srs.service /usr/lib/systemd/system/srs.service && sudo systemctl daemon-reload && sudo systemctl enable srs &&"
|
||||
@echo " sudo systemctl start srs"
|
||||
@echo "@see: https://github.com/ossrs/srs/wiki/v3_CN_LinuxService"
|
||||
|
||||
END
|
||||
fi
|
||||
|
@ -566,7 +569,7 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
|||
echo ""
|
||||
echo "Configure summary:"
|
||||
echo " ${SRS_AUTO_USER_CONFIGURE}"
|
||||
echo " ${SRS_AUTO_CONFIGURE}"
|
||||
echo " ${SRS_AUTO_CONFIGURE}"
|
||||
if [ $SRS_HLS = YES ]; then
|
||||
echo -e "${GREEN}HLS is enabled.${BLACK}"
|
||||
else
|
||||
|
@ -577,21 +580,11 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
|||
else
|
||||
echo -e "${GREEN}Note: StreamCaster is disabled.${BLACK}"
|
||||
fi
|
||||
if [ $SRS_KAFKA = YES ]; then
|
||||
echo -e "${GREEN}Kafka is enabled.${BLACK}"
|
||||
else
|
||||
echo -e "${YELLOW}Warning: Kafka is disabled.${BLACK}"
|
||||
fi
|
||||
if [ $SRS_HDS = YES ]; then
|
||||
echo -e "${YELLOW}Experiment: HDS is enabled.${BLACK}"
|
||||
else
|
||||
echo -e "${GREEN}Warning: HDS is disabled.${BLACK}"
|
||||
fi
|
||||
if [ $SRS_NGINX = YES ]; then
|
||||
echo -e "${GREEN}Nginx is enabled.${BLACK}"
|
||||
else
|
||||
echo -e "${GREEN}Note: Nginx is disabled.${BLACK}"
|
||||
fi
|
||||
if [ $SRS_DVR = YES ]; then
|
||||
echo -e "${GREEN}DVR is enabled.${BLACK}"
|
||||
else
|
||||
|
@ -602,11 +595,6 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
|||
else
|
||||
echo -e "${YELLOW}Warning: RTMP complex handshake is disabled, flash cann't play h264/aac.${BLACK}"
|
||||
fi
|
||||
if [ $SRS_FFMPEG_TOOL = YES ]; then
|
||||
echo -e "${GREEN}The FFMPEG tool is enabled.${BLACK}"
|
||||
else
|
||||
echo -e "${YELLOW}Warning: The FFMPEG tool is disabled, please use other tools for transcode/mux/ingest.${BLACK}"
|
||||
fi
|
||||
if [ $SRS_TRANSCODE = YES ]; then
|
||||
echo -e "${GREEN}The transcoding is enabled${BLACK}"
|
||||
else
|
||||
|
@ -677,16 +665,6 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
|||
else
|
||||
echo -e "${GREEN}Note: The gprof(GNU profile tool) is disabled.${BLACK}"
|
||||
fi
|
||||
if [ $SRS_ARM_UBUNTU12 = YES ]; then
|
||||
echo -e "${GREEN}The cross-build arm-ubuntu12(armhf, v7cpu) is enabled.${BLACK}"
|
||||
else
|
||||
echo -e "${GREEN}Note: The cross-build arm-ubuntu12(armhf, v7cpu)is disabled.${BLACK}"
|
||||
fi
|
||||
if [ $SRS_MIPS_UBUNTU12 = YES ]; then
|
||||
echo -e "${GREEN}The mips-ubuntu12 is enabled.${BLACK}"
|
||||
else
|
||||
echo -e "${GREEN}Note: The mips-ubuntu12 is disabled.${BLACK}"
|
||||
fi
|
||||
if [ $SRS_VALGRIND = YES ]; then
|
||||
echo -e "${GREEN}The valgrind is enabled.${BLACK}"
|
||||
else
|
||||
|
@ -705,12 +683,6 @@ if [ $SRS_EXPORT_LIBRTMP_PROJECT = NO ]; then
|
|||
ip=`ifconfig|grep "inet addr"| grep -v "127.0.0.1"|awk '{print $2}'|awk -F ':' 'NR==1 {print $2}'`
|
||||
echo ""
|
||||
echo "You can run 3rdparty applications:"
|
||||
if [ $SRS_NGINX = YES ]; then
|
||||
echo "\" sudo ./objs/nginx/sbin/nginx \" to start the nginx http server for hls"
|
||||
fi
|
||||
if [ $SRS_FFMPEG_TOOL = YES ]; then
|
||||
echo -e "\" ./objs/ffmpeg/bin/ffmpeg \" is used for live stream transcoding"
|
||||
fi
|
||||
if [ $SRS_HTTP_CALLBACK = YES ]; then
|
||||
echo -e "\" python ./research/api-server/server.py 8085 \" to start the api-server"
|
||||
fi
|
||||
|
@ -735,4 +707,6 @@ else
|
|||
echo -e "${GREEN}Please use the srs-librtmp project: ${BLACK}"
|
||||
echo -e "${GREEN} cd $SRS_EXPORT_LIBRTMP_PROJECT && make ${BLACK}"
|
||||
fi
|
||||
# Change to experiment.
|
||||
echo -e "${YELLOW}Warning: Notice srs-librtmp is deprecated and maybe removed in future.${BLACK}"
|
||||
fi
|
||||
|
|
|
@ -166,6 +166,30 @@ reload() {
|
|||
return 0
|
||||
}
|
||||
|
||||
logrotate() {
|
||||
# not start, exit
|
||||
load_process_info
|
||||
if [[ 0 -ne $? ]]; then failed_msg "SRS not start."; return 0; fi
|
||||
|
||||
ok_msg "Reopen log file of SRS(pid ${srs_pid})..."
|
||||
kill -s SIGUSR1 ${srs_pid}
|
||||
|
||||
ok_msg "Log rotated"
|
||||
return 0
|
||||
}
|
||||
|
||||
grace() {
|
||||
# not start, exit
|
||||
load_process_info
|
||||
if [[ 0 -ne $? ]]; then failed_msg "SRS not start."; return 0; fi
|
||||
|
||||
ok_msg "Gracefully quit for SRS(pid ${srs_pid})..."
|
||||
kill -s SIGQUIT ${srs_pid}
|
||||
|
||||
ok_msg "Gracefully quit"
|
||||
return 0
|
||||
}
|
||||
|
||||
menu() {
|
||||
case "$1" in
|
||||
start)
|
||||
|
@ -184,8 +208,17 @@ menu() {
|
|||
reload)
|
||||
reload
|
||||
;;
|
||||
rotate)
|
||||
logrotate
|
||||
;;
|
||||
grace)
|
||||
grace
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|status|restart|reload}"
|
||||
echo "Usage: $0 {start|stop|status|restart|reload|rotate|grace}"
|
||||
echo " reload Apply log file by not restarting SRS"
|
||||
echo " rotate For log rotate, to send SIGUSR1 to SRS to reopen the log file."
|
||||
echo " grace For gracefully quit, to send SIGQUIT to SRS."
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
|
|
|
@ -54,7 +54,7 @@ start() {
|
|||
ok_msg "Starting SRS-api..."
|
||||
# TODO: FIXME: set limit by, for instance, "ulimit -HSn 10000"
|
||||
# TODO: FIXME: write log to, for instance, the same dir of log.
|
||||
# TODO: FIXME: support deamon, without nohup.
|
||||
# TODO: FIXME: support daemon, without nohup.
|
||||
(cd ${ROOT}; nohup ${APP} ${CONFIG} >/dev/null 2>&1 &)
|
||||
|
||||
# check again after start server
|
||||
|
|
|
@ -9,56 +9,30 @@
|
|||
padding-top: 55px;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript" src="js/jquery-1.10.2.min.js"></script>
|
||||
<script type="text/javascript" src="js/bootstrap.min.js"></script>
|
||||
<script type="text/javascript" src="js/swfobject.js"></script>
|
||||
<script type="text/javascript" src="js/srs.page.js"></script>
|
||||
<script type="text/javascript" src="js/srs.utility.js"></script>
|
||||
<script type="text/javascript" src="js/winlin.utility.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(function(){
|
||||
update_nav();
|
||||
|
||||
var query = parse_query_string();
|
||||
var url = "srs_player.html?vhost=" + srs_get_player_vhost();
|
||||
|
||||
for (var key in query.user_query) {
|
||||
if (key == "vhost") {
|
||||
continue;
|
||||
}
|
||||
url += "&" + key + "=" + query[key];
|
||||
}
|
||||
|
||||
window.location.href = url;
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<a id="srs_index" class="brand" href="#">SRS</a>
|
||||
<div class="nav-collapse collapse">
|
||||
<ul class="nav">
|
||||
<li><a id="nav_srs_player" href="srs_player.html">SRS播放器</a></li>
|
||||
<li><a id="nav_srs_publisher" href="srs_publisher.html">SRS编码器</a></li>
|
||||
<li><a id="nav_srs_chat" href="srs_chat.html">SRS会议</a></li>
|
||||
<li><a id="nav_srs_bwt" href="srs_bwt.html">SRS测网速</a></li>
|
||||
<li><a id="nav_jwplayer6" href="jwplayer6.html">JWPlayer6播放器</a></li>
|
||||
<li><a id="nav_osmf" href="osmf.html">AdobeOSMF播放器</a></li>
|
||||
<li><a id="nav_vlc" href="vlc.html">VLC播放器</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<hr>
|
||||
<footer>
|
||||
<p><a href="https://github.com/ossrs/srs">SRS Team © 2013</a></p>
|
||||
</footer>
|
||||
</div>
|
||||
<script type="text/javascript" src="js/jquery-1.10.2.min.js"></script>
|
||||
<script type="text/javascript" src="js/bootstrap.min.js"></script>
|
||||
<script type="text/javascript" src="js/swfobject.js"></script>
|
||||
<script type="text/javascript" src="js/srs.page.js"></script>
|
||||
<script type="text/javascript" src="js/srs.utility.js"></script>
|
||||
<script type="text/javascript" src="js/winlin.utility.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(function(){
|
||||
update_nav();
|
||||
|
||||
var query = parse_query_string();
|
||||
var url = "srs_chat.html?vhost=" + srs_get_player_vhost();
|
||||
|
||||
for (var key in query.user_query) {
|
||||
if (key == "vhost") {
|
||||
continue;
|
||||
}
|
||||
url += "&" + key + "=" + query[key];
|
||||
}
|
||||
|
||||
setTimeout(function(){
|
||||
window.location.href = url;
|
||||
}, 100);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// to query the swf anti cache.
|
||||
function srs_get_version_code() { return "1.31"; }
|
||||
function srs_get_version_code() { return "1.33"; }
|
||||
|
||||
/**
|
||||
* player specified size.
|
||||
|
@ -18,13 +18,6 @@ function srs_get_player_vhost() { return "players"; }
|
|||
function srs_get_api_server_port() { return 8085; }
|
||||
// the srs http server port
|
||||
function srs_get_srs_http_server_port() { return 8080; }
|
||||
// get the stream published to vhost,
|
||||
// generally we need to transcode the stream to support HLS and filters.
|
||||
// for example, src_vhost is "players", we transcode stream to vhost "players_pub".
|
||||
// if not equals to the player vhost, return the orignal vhost.
|
||||
function srs_get_player_publish_vhost(src_vhost) { return (src_vhost != srs_get_player_vhost())? src_vhost:(src_vhost + "_pub"); }
|
||||
// for chat, use rtmp only vhost, low latecy, without gop cache.
|
||||
function srs_get_player_chat_vhost(src_vhost) { return (src_vhost != srs_get_player_vhost())? src_vhost:(src_vhost + "_chat"); }
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -50,6 +43,15 @@ function user_extra_params(query, params) {
|
|||
var server = (query.server == undefined)? window.location.hostname:query.server;
|
||||
var vhost = (query.vhost == undefined)? window.location.hostname:query.vhost;
|
||||
|
||||
// Note that ossrs.net provides only web service,
|
||||
// that is migrating to r.ossrs.net
|
||||
if (vhost == "ossrs.net") {
|
||||
vhost = "r.ossrs.net";
|
||||
}
|
||||
if (server == "ossrs.net") {
|
||||
server = "r.ossrs.net";
|
||||
}
|
||||
|
||||
for (var key in query.user_query) {
|
||||
if (key == 'app' || key == 'autostart' || key == 'dir'
|
||||
|| key == 'filename' || key == 'host' || key == 'hostname'
|
||||
|
@ -59,7 +61,10 @@ function user_extra_params(query, params) {
|
|||
) {
|
||||
continue;
|
||||
}
|
||||
queries.push(key + '=' + query[key]);
|
||||
|
||||
if (query[key]) {
|
||||
queries.push(key + '=' + query[key]);
|
||||
}
|
||||
}
|
||||
|
||||
return queries;
|
||||
|
@ -75,12 +80,21 @@ function user_extra_params(query, params) {
|
|||
function build_default_rtmp_url() {
|
||||
var query = parse_query_string();
|
||||
|
||||
var schema = (query.schema == undefined)? "rtmp":query.schema;
|
||||
var server = (query.server == undefined)? window.location.hostname:query.server;
|
||||
var port = (query.port == undefined)? schema=="http"?80:1935:query.port;
|
||||
var vhost = (query.vhost == undefined)? window.location.hostname:query.vhost;
|
||||
var app = (query.app == undefined)? "live":query.app;
|
||||
var stream = (query.stream == undefined)? "demo":query.stream;
|
||||
var schema = (!query.schema)? "rtmp":query.schema;
|
||||
var server = (!query.server)? window.location.hostname:query.server;
|
||||
var port = (!query.port)? schema=="http"?80:1935:query.port;
|
||||
var vhost = (!query.vhost)? window.location.hostname:query.vhost;
|
||||
var app = (!query.app)? "live":query.app;
|
||||
var stream = (!query.stream)? "livestream":query.stream;
|
||||
|
||||
// Note that ossrs.net provides only web service,
|
||||
// that is migrating to r.ossrs.net
|
||||
if (vhost == "ossrs.net") {
|
||||
vhost = "r.ossrs.net";
|
||||
}
|
||||
if (server == "ossrs.net") {
|
||||
server = "r.ossrs.net";
|
||||
}
|
||||
|
||||
var queries = [];
|
||||
if (server != vhost && vhost != "__defaultVhost__") {
|
||||
|
@ -99,16 +113,25 @@ function build_default_rtmp_url() {
|
|||
function build_default_publish_rtmp_url() {
|
||||
var query = parse_query_string();
|
||||
|
||||
var schema = (query.schema == undefined)? "rtmp":query.schema;
|
||||
var server = (query.server == undefined)? window.location.hostname:query.server;
|
||||
var port = (query.port == undefined)? schema=="http"?80:1935:query.port;
|
||||
var vhost = (query.vhost == undefined)? window.location.hostname:query.vhost;
|
||||
var app = (query.app == undefined)? "live":query.app;
|
||||
var stream = (query.stream == undefined)? "demo":query.stream;
|
||||
var schema = (!query.schema)? "rtmp":query.schema;
|
||||
var server = (!query.server)? window.location.hostname:query.server;
|
||||
var port = (!query.port)? schema=="http"?80:1935:query.port;
|
||||
var vhost = (!query.vhost)? window.location.hostname:query.vhost;
|
||||
var app = (!query.app)? "live":query.app;
|
||||
var stream = (!query.stream)? "demo":query.stream;
|
||||
|
||||
// Note that ossrs.net provides only web service,
|
||||
// that is migrating to r.ossrs.net
|
||||
if (vhost == "ossrs.net") {
|
||||
vhost = "r.ossrs.net";
|
||||
}
|
||||
if (server == "ossrs.net") {
|
||||
server = "r.ossrs.net";
|
||||
}
|
||||
|
||||
var queries = [];
|
||||
if (server != vhost && vhost != "__defaultVhost__") {
|
||||
queries.push("vhost=" + srs_get_player_chat_vhost(vhost));
|
||||
queries.push("vhost=" + vhost);
|
||||
}
|
||||
if (query.shp_identify) {
|
||||
queries.push("shp_identify=" + query.shp_identify);
|
||||
|
@ -125,11 +148,20 @@ function build_default_publish_rtmp_url() {
|
|||
function build_default_bandwidth_rtmp_url() {
|
||||
var query = parse_query_string();
|
||||
|
||||
var server = (query.server == undefined)? window.location.hostname:query.server;
|
||||
var port = (query.port == undefined)? 1935:query.port;
|
||||
var server = (!query.server)? window.location.hostname:query.server;
|
||||
var port = (!query.port)? 1935:query.port;
|
||||
var vhost = "bandcheck.srs.com";
|
||||
var app = (query.app == undefined)? "app":query.app;
|
||||
var key = (query.key == undefined)? "35c9b402c12a7246868752e2878f7e0e":query.key;
|
||||
var app = (!query.app)? "app":query.app;
|
||||
var key = (!query.key)? "35c9b402c12a7246868752e2878f7e0e":query.key;
|
||||
|
||||
// Note that ossrs.net provides only web service,
|
||||
// that is migrating to r.ossrs.net
|
||||
if (vhost == "ossrs.net") {
|
||||
vhost = "r.ossrs.net";
|
||||
}
|
||||
if (server == "ossrs.net") {
|
||||
server = "r.ossrs.net";
|
||||
}
|
||||
|
||||
return "rtmp://" + server + ":" + port + "/" + app + "?key=" + key + "&vhost=" + vhost;
|
||||
}
|
||||
|
@ -145,6 +177,12 @@ function build_default_bandwidth_rtmp_url() {
|
|||
function build_default_hls_url() {
|
||||
var query = parse_query_string();
|
||||
|
||||
// Note that ossrs.net provides only web service,
|
||||
// that is migrating to r.ossrs.net
|
||||
if (query.hls_vhost == "ossrs.net") {
|
||||
query.hls_vhost = "r.ossrs.net";
|
||||
}
|
||||
|
||||
// for http, use hls_vhost to override server if specified.
|
||||
var server = window.location.hostname;
|
||||
if (query.server != undefined) {
|
||||
|
@ -153,11 +191,11 @@ function build_default_hls_url() {
|
|||
server = query.hls_vhost;
|
||||
}
|
||||
|
||||
var port = (query.hls_port == undefined)? window.location.port:query.hls_port;
|
||||
var app = (query.app == undefined)? "live":query.app;
|
||||
var stream = (query.stream == undefined)? "demo":query.stream;
|
||||
var port = (!query.hls_port)? window.location.port:query.hls_port;
|
||||
var app = (!query.app)? "live":query.app;
|
||||
var stream = (!query.stream)? "demo":query.stream;
|
||||
|
||||
if (port == "" || port == null || port == undefined) {
|
||||
if (!port) {
|
||||
port = 8080;
|
||||
}
|
||||
|
||||
|
|
|
@ -118,6 +118,9 @@ SrsPlayer.prototype.start = function(url) {
|
|||
flashvars, params, attributes,
|
||||
function(callbackObj){
|
||||
self.callbackObj = callbackObj;
|
||||
if (!callbackObj.success) {
|
||||
console.error('Initialize player failed:'); console.error(callbackObj);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -94,6 +94,7 @@
|
|||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<img src='https://ossrs.net:8443/gif/v1/sls.gif?site=ossrs.net&path=/player/jwplayer'/>
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<img src='https://ossrs.net:8443/gif/v1/sls.gif?site=ossrs.net&path=/player/osmf'/>
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<img src='https://ossrs.net:8443/gif/v1/sls.gif?site=ossrs.net&path=/player/bwt'/>
|
||||
<div class="navbar navbar-fixed-top">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
|
@ -34,39 +35,58 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="alert alert-info fade in">
|
||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||
<strong><span>Usage:</span></strong> <span>点击“开始测速”即可测带宽,最大可测试带宽由服务器限制</span>
|
||||
<div name="detect_flash">
|
||||
<div id="main_flash_alert" class="alert alert-danger fade in hide">
|
||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||
<strong><p>Usage:</p></strong>
|
||||
<p>
|
||||
请点击下面的图标,启用Flash
|
||||
</p>
|
||||
<p>
|
||||
若没有见到这个图标,Chrome浏览器请打开
|
||||
<span class="text-info">chrome://settings/content/flash</span> 并修改为"Ask first"。
|
||||
</p>
|
||||
</div>
|
||||
<div id="main_flash_hdr" class="hide">
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-inline">
|
||||
URL:
|
||||
<input type="text" id="txt_url" class="input-xxlarge" value=""></input>
|
||||
<button class="btn btn-primary" id="btn_play">开始测速</button>
|
||||
</div>
|
||||
<div id="main_modal" class="modal hide fade">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3>SRS Bandwidth Check</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row-fluid">
|
||||
<div class="span1"></div>
|
||||
<div class="span10">
|
||||
<div class="progress progress-striped active" id="pb_buffer_bg">
|
||||
<div class="bar" style="width: 0%;" id="progress_bar"></div>
|
||||
|
||||
<div id="main_content" class="hide">
|
||||
<div class="alert alert-info fade in">
|
||||
<button type="button" class="close" data-dismiss="alert">×</button>
|
||||
<strong><span>Usage:</span></strong> <span>点击“开始测速”即可测带宽,最大可测试带宽由服务器限制</span>
|
||||
</div>
|
||||
<div class="form-inline">
|
||||
URL:
|
||||
<input type="text" id="txt_url" class="input-xxlarge" value=""></input>
|
||||
<button class="btn btn-primary" id="btn_play">开始测速</button>
|
||||
</div>
|
||||
<div id="main_modal" class="modal hide fade">
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||
<h3>SRS Bandwidth Check</h3>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="row-fluid">
|
||||
<div class="span1"></div>
|
||||
<div class="span10">
|
||||
<div class="progress progress-striped active" id="pb_buffer_bg">
|
||||
<div class="bar" style="width: 0%;" id="progress_bar"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="span1"></div>
|
||||
</div>
|
||||
<div class="span1"></div>
|
||||
</div>
|
||||
<div id="check_status">status</div>
|
||||
<div id="check_info">info</div>
|
||||
<div id="check_status">status</div>
|
||||
<div id="check_info">info</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-primary" data-dismiss="modal" aria-hidden="true"> 关闭 </button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-primary" data-dismiss="modal" aria-hidden="true"> 关闭 </button>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
</div>
|
||||
|
||||
<footer>
|
||||
<p></p>
|
||||
<p><a href="https://github.com/ossrs/srs">SRS Team © 2013</a></p>
|
||||
</footer>
|
||||
<div class="container">
|
||||
|
@ -85,15 +105,57 @@
|
|||
<script type="text/javascript" src="js/winlin.utility.js"></script>
|
||||
<script type="text/javascript" src="srs_bwt/src/srs.bandwidth.js"></script>
|
||||
<script type="text/javascript">
|
||||
var bandwidth = null;
|
||||
var __on_flash_ready = null;
|
||||
|
||||
$(function(){
|
||||
// 探测Flash是否正常启用。
|
||||
$('#main_flash_hdr').html(
|
||||
'\
|
||||
<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="100%" height="100%"> \
|
||||
<param name="movie" value="srs_player/release/srs_player.swf"> \
|
||||
<param name="quality" value="autohigh"> \
|
||||
<param name="swliveconnect" value="true"> \
|
||||
<param name="allowScriptAccess" value="always"> \
|
||||
<param name="bgcolor" value="#0"> \
|
||||
<param name="allowFullScreen" value="true"> \
|
||||
<param name="wmode" value="opaque"> \
|
||||
<param name="FlashVars" value="log=1"> \
|
||||
<param name="flashvars" value="id=1&on_player_ready=__on_flash_ready"> \
|
||||
<embed src="srs_player/release/srs_player.swf" width="100%" height="100%" \
|
||||
quality="autohigh" bgcolor="#0" align="middle" allowfullscreen="true" allowscriptaccess="always" \
|
||||
type="application/x-shockwave-flash" swliveconnect="true" wmode="opaque" \
|
||||
flashvars="id=1&on_player_ready=__on_flash_ready" \
|
||||
pluginspage="http://www.macromedia.com/go/getflashplayer"> \
|
||||
</object> \
|
||||
'
|
||||
);
|
||||
$('#main_flash_hdr').show();
|
||||
|
||||
var showFlashHdr = setTimeout(function(){
|
||||
$('#main_flash_alert').show();
|
||||
}, 300);
|
||||
|
||||
__on_flash_ready = function (id) {
|
||||
clearTimeout(showFlashHdr);
|
||||
|
||||
$('#main_flash_alert').hide();
|
||||
$('#main_flash_hdr').hide();
|
||||
$('#main_content').show();
|
||||
|
||||
autoLoadPage();
|
||||
};
|
||||
});
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
var bandwidth = null;
|
||||
|
||||
var autoLoadPage = function() {
|
||||
srs_init_bwt("#txt_url");
|
||||
|
||||
$("#btn_play").click(on_click_play);
|
||||
$("#main_modal").on("show", on_start_bandwidth_test);
|
||||
$("#main_modal").on("hide", on_stop_bandwidth_test);
|
||||
});
|
||||
};
|
||||
|
||||
function on_click_play() {
|
||||
$("#check_status").text("");
|
||||
|
@ -127,8 +189,7 @@
|
|||
}
|
||||
bandwidth.on_srs_info = function(srs_server, srs_primary, srs_authors, srs_id, srs_pid, srs_server_ip) {
|
||||
$("#check_info").text(
|
||||
"server:" + srs_server + ", primary:" + srs_primary + ", authors:" + srs_authors +
|
||||
", srs_id:" + srs_id + ", srs_pid:" + srs_pid + ", ip:" + srs_server_ip
|
||||
"server:" + srs_server + ", srs_id:" + srs_id + ", srs_pid:" + srs_pid + ", ip:" + srs_server_ip
|
||||
);
|
||||
}
|
||||
bandwidth.on_error = function(code) {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue