Compare commits

...
55 Commits
Author SHA1 Message Date
Unbit 6adbc37a31 removed old-style changelog 2013-08-23 14:57:06 +02:00
Unbit 688d3fff8c fixed python3 static files handling 2013-08-23 14:51:18 +02:00
Unbit c0b079deb0 backported python3 latin1 fix from 1.9 2013-07-02 16:22:20 +02:00
Unbit 9b30c8683b fixed backtrace-depth 2013-05-23 19:40:21 +02:00
Unbit 9113812b0d fixed python3 pyargv 2013-05-19 05:04:42 +02:00
Unbit 1abe9f2d12 fixed mule_msg 2013-05-18 18:27:11 +02:00
Unbit 9a37b3653f uWSGI 1.4.9 2013-03-09 10:01:34 +01:00
Unbit 65ad341a31 backported cache_update for lua and fixed its lock handling 2013-03-07 13:28:50 +01:00
Unbit bd31548903 re-try semop() on interrupt 2013-03-07 13:17:46 +01:00
Unbit dd536cf7ea removed jvm and jwsgi plugin as in 1.9 we have a really working implementation 2013-03-06 20:08:29 +01:00
Unbit efa27dfc6c better broodlord num computation 2013-03-06 19:56:55 +01:00
Unbit 91b14e0b34 improved broodlord mode 2013-03-06 19:13:32 +01:00
Unbit 74b3d25bcf call ERR_clear_error after each https session close 2013-03-06 10:36:05 +01:00
Unbit 3857e26e4c avoid crashing carbon on master shutdown 2013-03-03 13:43:55 +01:00
Unbit c7d3a27225 backported http-socket-modifier1/2 2013-03-02 16:25:17 +01:00
Unbit 4f50b4aafc completetd gemspec 2013-03-02 14:58:58 +01:00
Unbit d172fb4909 fixed gem generation 2013-03-02 14:49:03 +01:00
Unbit c842bb4917 allows building uwsgi as a gem 2013-03-02 14:37:14 +01:00
Unbit d6da6848be manage https re-handshake and fix gevent timeout management 2013-03-02 09:54:10 +01:00
Unbit b1caf56f49 various minor fixes in gateway initialization 2013-03-02 08:35:56 +01:00
Unbit 00c243bcce backported --for-glob 2013-03-01 15:23:38 +01:00
Unbit 575dd6beee backported add_timer and add_rb_timer for perl/psgi plugin 2013-03-01 15:20:40 +01:00
unbit 645d021d73 Merge pull request #166 from prymitive/carbon_hostname14
backported carbon hostname patch to 1.4.x
2013-03-01 06:18:52 -08:00
Łukasz Mierzwa 0ca320e5fd backported carbon hostname patch to 1.4.x 2013-03-01 15:15:46 +01:00
Unbit 7879a010e8 backported negative --log-alarm 2013-02-27 04:39:55 +01:00
Unbit 43dd1029ad fixed usage of ipcsem on linux 2013-02-27 04:26:59 +01:00
Unbit ce7d84b865 try to avoid the need to sync cache_first_available_item with cache_unused_stack 2013-02-27 01:43:03 +01:00
Unbit 7ab1795075 let's prepare for 1.4.7 2013-02-27 01:27:49 +01:00
Unbit e1ce4e1011 backporetd new carbon plugin and stats pusher subsystem 2013-02-27 01:26:24 +01:00
Unbit 0c02a5104a removed the old/broken/useless mono plugin, a new one will be in 1.9 2013-02-25 08:39:43 +01:00
Unbit 0e244fc59c added support for ruby 2 2013-02-25 07:34:34 +01:00
Unbit 5d6086c84a allows --attach-daemon without workers 2013-02-23 14:46:41 +01:00
Unbit a45be4f7a9 backported perl async fixes from 1.9 2013-02-23 13:35:41 +01:00
Unbit dd63bef92e backported --perl-arg and --perl-args 2013-02-23 13:28:51 +01:00
Unbit 621a05d879 another heroku python fix 2013-02-23 13:26:05 +01:00
Unbit b857690caf backported python plugin new build system (heroku friendly) 2013-02-23 12:07:45 +01:00
Unbit edb0a72dfd fixed a refcnt bug in psgi plugin 2013-02-23 08:26:08 +01:00
Unbit da4af442ad prepare for uWSGI 1.4.6 2013-02-20 16:03:27 +01:00
Unbit 04ff580075 improved muleloop in uwsgidecoraotors 2013-02-19 07:12:44 +01:00
Unbit 5925db13cf backported more logvars 2013-02-18 13:09:53 +01:00
Unbit d283fd1aae fixed master + emperor 2013-02-12 16:44:14 +01:00
Unbit 345b22d8f0 forget to reset SIGCHLD to SIG_DFL 2013-02-10 20:12:47 +01:00
Unbit b8fc89166d reset sigmask on startup 2013-02-10 19:52:50 +01:00
Unbit 50ffb9d258 reapply fixed-SERVER_PORT-in-routers-when-shared-sockets-are.patch 2013-02-09 17:34:31 +01:00
Unbit 9ae1b26d52 fixed suspend when harakiri is in place 2013-02-07 14:11:24 +01:00
Unbit f281d21a1b backported improved alarm_xmpp plugin 2013-01-31 09:59:54 +01:00
Unbit b9a2b92005 fixed PTHREAD_MUTEX_ROBUST [4] 2013-01-30 18:28:23 +01:00
Unbit 92a26d4ff6 fixed PTHREAD_MUTEX_ROBUST [3] 2013-01-30 18:26:24 +01:00
Unbit 51360416a7 fixed PTHREAD_MUTEX_ROBUST [2] 2013-01-30 18:20:22 +01:00
Unbit c7bc98a50c fixed PTHREAD_MUTEX_ROBUST 2013-01-30 18:16:24 +01:00
Unbit b4b5c0175a added __USE_UNIX98 to pthread.h 2013-01-30 18:14:37 +01:00
Unbit 7ed3eb36ee fixed PTHREAD_PRIO_INHERIT 2013-01-30 18:09:48 +01:00
Unbit 05c475f597 added --thunder-lock 2013-01-30 18:02:03 +01:00
Unbit c750dfc1e3 Revert "fixed SERVER_PORT in routers when shared sockets are in place"
This reverts commit 01b14f4395.
2013-01-30 16:57:59 +01:00
Unbit 01b14f4395 fixed SERVER_PORT in routers when shared sockets are in place 2013-01-30 16:32:19 +01:00
49 changed files with 855 additions and 1366 deletions
-679
View File
@@ -1,679 +0,0 @@
*** current ***
* 1.4.1
- fixed typos in corerouter plugins
- fixed offloading when the number of threads is higher than 1
- fixed static_maps for non-existent paths
- fixed uwsgi_connect() on modern Linux systems to reset the socket to blocking mode
*** november 2012 ***
* 1.4
- gevent improvements
- improved http/https router and fastrouter
- Go official support
- a new set of infos are exported to the stats system
- improved systemd support
- log filtering and routing
- improved tracebacker
- offload transfer for static files, and network transfers
- matheval support
- plugins can be written in Obj-C
- smart attach daemon
- added support for PEP 405 virtualenvs
- rawrouter with xclient support
- internal routing plugin for cache
*** semptember 2012 ***
* 1.3
- python tracebacker
- user-governed harakiri
- simplified external plugin development
- Linux namespace mountpoint improvements
- secured subscription system
- merged routers codebase (fastrouter, http, rawrouter)
- https support in the http router
- config report at the end of uWSGI build process
- improved subscription system (multicast and unix socket)
- custom options
- graceful reloads on shared sockets
- configurable log-master buffer size
- extreme-optimizations for the stats subsystem
- redislog and mongodblog plugins
- added python logger
- mongodb and postgres imperial monitors
- implemented psgix.logger and psgix.cleanup
- full rack spec compliance
- preliminary ipv6 support
- gevent graceful reloads
- support for multiple loggers and logformat
- lazy-apps to load apps after fork() but without changing reloading subsystem
- emperor heartbeat subsystem
- cheaper busyness plugin
- pluggable clock sources
- added router_rewrite and router_http plugins
- external spoolers
- support for section:// and fd:// loaders
- alarm subsystem (with curl and xmpp plugins)
*** april 2012 ***
* 1.2 [20120430]
- PyPy support
- Improved gevent support with threads
- Python auto-reload subsystem
- added --spooler-max-tasks
- pthread robust mutexes support in Linux and Solaris
- posix semaphores support in FreeBSD9
- thread-safe ctime() reporting
- interval support in cron subsystem
- improved syslog support
- better management of disconnected clients
- static files serving improvements
- another set of multithreading optimizations
- minor fixes in the Rack plugin
- Upstart socket-activation support
*** march 2012 ***
* 1.1 [20120317]
- new options parser subsystem
- improved php support
- multiple spooler with multiprocessing
- segmentation fault and floating point exceptions manager
- never-swap option
- zergpool plugin
- perl/psgi multiple interpreters support
- deadlock detector
- pluggable cheaper algos
- new internal routing susbsystem
- preliminary support for config logic
- log rotation infrastructure
- support for paste loggers
- threading improvements
- plugins can now mapped to specific modifiers
- <app> tag is deprecated (use mount option)
- report startup time for apps
- reintroduced expat support
- reintroduced remote spooler plugin
- various fastrouter optimizations
- added ruby rvm support
*** december 2011 ***
* 1.0 [20111230]
- adaptive process spawning (--cheaper option)
- new control options --stop, --reload, --suspend, --resume, --pause
- stats framework
- new subscription system
- support for mime types in static file serving
- posix capablities support
- uWSGI mules and farms
- support for multiple --touch-reload options
- new logging subsystem
- new custom locking subsystem
- process name handling
- better (and faster) HTTP parser
- perl and python threading improvements
- new plugins: rrdtool, carbon, cgi, php
- various improvements in the Rack/ruby plugin
- Linux KSM support
- refactored ping and nagios plugins
- support for signals in lazy mode
- optimized static-file serving
- support for linux unshare()
*** august 2011 ***
* 0.9.9 [20110829]
- various spooler improvements
- upload progress optimizations and fixes
- new emperor mode: Tyrant
- allows multiple --ini options
- better binary path detection
- gevent loop engine support
- resolve domain names in socket logging
- snmp fixes and reintroduction of the snmp-api
- fixed grunt mode
- you can specify build profile via env var UWSGI_PROFILE
- reintroduction of string-based multiapp
- new option --emperor-throttle
- improved queue and sharedarea subsystems
- uWSGI can now be built as a shared library
- new api attribute: uwsgi.magic_table
- improved apache2 module
- new option --pyshell
- allow threads in gateways
- fastrouter improvements
- the application list is now shared and exported to the api
- allows setting the thread stack size
- UWSGI_APPID for better multiapp hosting
- better reloading in lazy mode
- native pump support
- various rack fixes
- support for attaching binary data in the executable
- new option --set
- extreme-optimized http protocol parser
- WSGI handler optimizations
*** july 2011 ***
* 0.9.8.3 [20110723]
- implemented uwsgi.SymZipImporter to load embedded zip files
- OSX Lion is officially supported
- fixed xinetd support (example file added in contrib)
- suppot for systemd socket activation
- added --freebind option (Linux only)
* 0.9.8.2 [20110719]
- fixed an ini and yaml parsing bug spotted by Raffaele Colace
- spooler has been extremely improved
- new option --chown-socket
- added uwsgidecorators for elegant uwsgi api access from python
- the rack plugin is now stable
- support for embedding config and generic files in the server binary
- high-performance cache-server
- accept() is now locked on all threads in the same workers
- preliminary implementation of hooks in emperor
- support for C++ in server core
- tcp port auto-bind
- implemented workers, workerN and spooler signal target
- prefork/multithread uwsgi.signal_wait() implementation
- export uwsgi.node in WSGI vars
- new option --import (python plugin)
- support for unlimited number of Linux cgroups
- broodlord mode
*** june 2011 ***
* 0.9.8.1 [20110625]
- the build system has been improved
- various threading fixes
- fix python GIL status after reload
- new option --propagate-touch
- fixed uwsgi.sendfile
- fixed readline() support in wsgi.input
- fixed dynamic touch reload
- new option --logto2
- export %c in config files
- fixed libyaml support
- support passing modifiers in subscription system
- reset random seed in spooler
- subscribe from a list in a text file
- allow binding on port 0 (auto-assignment)
- reset random seed on grunt
- fix vhost mode for empty hostname
- fixed python3+virtualenv support
- tasks are now allowed to chdir() in spooler
- better zeromq+clustering support
- clustering has been refactored
- fixed rpc
- report correct worker id in cheap mode
- fixed a fd-leak in attach-daemon
- use setsid() in attach-daemon
- zerg mode
- added psgix.harakiri
- allows magic vars in sqlite3 config db
- added UWSGI_FASTROUTER_KEY var
- slowdown async-queue-is-full messages
- new option --cron
- --vassals-start-hook and --vassals-stop-hook
- the proxy plugin has been removed
* 0.9.8 [20110605]
- support for --callable in virtualhosting mode
- a NetBSD fix
- abstract unix socket can be prefixed with \0 (nginx-style)
- add /lib to the linker in sun-like systems
- a mercy mode of 5 seconds is enabled by default on SIGINT/SIGQUIT
* 0.9.8-rc4 [20110602]
- fixed REMOTE_ADDR when --protocol=http
- official support for OpenIndiana
- added a welcome.py test script
- new api attribute uwsgi.version_info
- improved the admin plugin
- two new management flag for backlog queue monitoring
- fixed uwsgi_log for bigger loglines
- new option --early-emperor to allows out-of-jail emperors
- emperor can now spawn other emperors (sub-emperors)
- fixed idle mode in single-process
- fixed solaris iovec
*** may 2011 ***
* 0.9.8-rc3 [20110530]
- snapshotting support
- fixed python 3.x spooler
- improvements for grunt processes
- better abstract unix socket
- --log-socket allows logging to generic DGRAM sockets
- a bunch of solaris fixes
- new option --no-fd-passing for fastrouter
- --fastrouter-subscription-slot to set the number of slot in subscription server
- unlimited shared sockets
- fixed netlink compilation
- auto-reconnect on emperor+amqp server disconnection
- various emperor fixes
- unlimited fastrouter sockets
- better cgroup support
- --add-header option allow adding of custom HTTP response headers
- cheap and idle operational modes
* 0.9.8-rc2 [20110521]
- new option --die-on-term
- fixed touch reload
- a couple of optimizations for wsgi.input
- systemd integration
* 0.9.8-rc1 [20110514]
- massive code cleanup and refactoring
- added vassals loyalty concept
- fixed virtualhosting with dynamic virtualenv
- fixed reloading on grand-central-dispatch-enabled OSX
- improved PSGI support with uGreen and async support
- improved Rack support with complete fiber+async in ruby 1.9
- support for JSON config files
- native multi-protocol support (added fastcgi and http)
- Mongrel2 support
- support for templates in vassals
- various threading fixes
- gcc-4.6 support
- support for logging via zeromq
- support for configuration passed via pipe/stdin
- pythonpath entries are now unlimited
- socket entries are unlimited
- pythonpath can be a glob
- lazy mode added
- new language-independent profiling subsystem
- support for configuration stored in a sqlite3 db
- allow workers to survive to syslogd death (when --log-syslog is used)
- fix traceback in Python 3.x
- support for uwsgi signals in threads
- plugin autoloading
- graceful reloading for threads
- new wsgi.input object
- support for alternative allocators (tcmalloc and jemalloc)
*** april 2011 ***
* 0.9.7.2 [20110406]
- new option --touch-reload <file> to reload the stack on <file> modification
--static-map <mountpoint=documentroot> allows to serve static files
- fixed --post-limit management
- disallow empty socket names
- implemented exception_info WSGI support
- new options --reload-on-as <n> and --reload-on-rss <n> allows
to recycle workers when their memory usage is higher than <n> MB
- fixed syslog support (use --log-syslog[=facility] to enable it)
- improved plugin loading system
- added support for RabbitMQ as event dispatcher for the Emperor
- fixed FreeBSD memory report
- PSGI plugin can be compiled without ithreads
- various Emperor fixes
- fixed a regression with setgroups()
- support for shared sockets (used in jails within network namespaces)
*** march 2011 ***
* 0.9.7.1 [20110326]
- fixed python stackless support
- added persistence for queue
- forbid daemonizing in vassal mode
- modifier1 30 is available again
- allow python modules to be mapped/aliased via http
- added --pidfile2 and --logfile-chown
- added UWSGI_CACHE_GET dynamic variable
- 304/If-Modified-Since support for --check-static
- option --check-cache for integrated caching
- option --map-socket to assign specific workers to socket
- fixed unix fd passing on older OSX versions
- fixed post-buffering without pep3333-input
- fixed python threading without uwsgi cores
- support for Linux network namespace
- build with sys.abiflags if necessary
* 0.9.7 [20110317]
- fixed psgi compilation on GNU systems
- improved --pep3333-input
- better error reporting on failed open/fopen
- fixed uGreen
- added greenlet support
- various solaris fixes
- new help system
- updated async support
- fixed uwsgi.cache_get in python
* 0.9.7-rc3 [20110312]
- added support for persistent cache (--cache-store <filename>)
- less verbose file monitoring
- fixed a race condition in emperor startup
- fixed erlang empty list encoding
- improved snmp support
- fixed cache modifier 111 for 3 and 4
- preliminary cpu-affinity support (Linux only)
- fixed ldap support
- auto-configure ldap compilation
- added --allowed-modifiers (allow only a subset of modifiers)
- fixed a bug with getopt_long
* 0.9.7-rc2 [20110309]
- added cron-like interface to signal framework
- improved Linux namespaces support
- fixed multithreading + --max-requests
- added support for reference in configuration files
* 0.9.7-rc1 [20110307]
- export %v in emperor mode
- fixed signal race condition in server reload
- fixed http router post handling bug
- added uwsgi.erlang_register_process in pyerl plugin
- fixed unix socket inherit
- fixed linux namespace support in recent kernel/gcc
- ported threading to python 3.2
- add build date to uWSGI startup info
- do not allow clustering without defining a socket
- kill all the gateways/daemons on startup errors
- fixed vacuum after chdir()
- fixed gateways reload
- re-added support for OpenBSD and NetBSD
- fixed post-buffering in python
- use erlang binary for python string
- fixed memory leak in pyerl plugin
- removed broken log rotation (post-poned)
- fixed no_argument options in ini and yaml parsing
* 0.9.7-beta1 [20110301]
- fully modular re-design
- advanced build system with presets
- threading support
- emperor mode for massive auto-hosting
- caching subsystem
- message queue (even stacked) support
- improved server reloading system
- support for Linux Cgroups and Namespaces
- integrated upload progress
- Clustering infrastructure via multicast, broadcast or subscriptions
- support for attaching/monitoring external apps to the master process
- improved virtualhosting mode
- extremely improved Python support with better usage of multiple interpreters
- improved multiple apps support
- Production ready, evented HTTP router/proxy/load-balancer
- Production ready, evented uwsgi router/proxy/load-balancer
- new Erlang stack
- Internal signal subsystem
- support for RubyOnRails and Rack apps
- A huge series of fixes and optimizations
*** february 2011 ***
* 0.9.6.8 [20110207]
- fixed a bug when using --limit-as
- fixed a erlang buffer initialization
- added --ignore-sigpipe
- added --master-as-root
*** january 2011 ***
* 0.9.6.7 [20110130]
- a huge amount of async optimizations and fixes
- --logdate takes an optional strftime-like value
- follow $PATH on reloading
- uwsgi.core is exported in WSGI env
- uwsgi.log() respect for --logdate
- initial banner respect for --logdate
- fixed --post-buffering
- default listen backlog queue is now 100
- Python 3 support is no more marked as experimental
- Python 3.2 support
- new option --chroot-reload will force a reload of the uWSGI stack after a chroot
- fixed a typo in INI parsing
*** december 2010 ***
* 0.9.6.6 [20101230]
- support for YAML configuration files
- backported python module aliasing from 0.9.7-dev
- better apache2 module (support for SetEnv directive, fixed REQUEST_URI and improved connection handling)
- uwsgi.post_fork_hook implementation (to execute function after fork()) (thanks George Kollias)
- option --gid calls setgroups() after setgid() (thanks Jorge Cardona)
- fixed uGreen compilation (and uGreen is now built by default)
- fixed timeout and thundering herd problem in async modes (many thanks to Test157 for giving us a good async-test-app)
- disable TCP_INFO in older Linux kernels (thanks Bo Shi)
- enable TCP_INFO in FreeBSD (limited usage due to FreeBSD kernel support)
- fixed static virtualhosting mode using xml files (thanks Guido Notari of Link I.T. spa)
- new option --close-on-exec (thanks Jean-Baptiste Quenot)
- use HTTP_HOST var (and fallback to SERVER_NAME) in virtual hosting mode
- fixed a buffer overflow in automatic socket_name allocation (spotted by Riccardo Magliocchetti)
- Official support for Nexenta
*** september 2010 ***
* 0.9.6.5 [20100929]
- PEP 3333 support
- fix --pythonpath with --wsgi-file
- x-wsgiorg.uwsgi.version renamed to uwsgi.version
* 0.9.6.4 [20100925]
- fix a stupid bug in conditional logging backport
* 0.9.6.3 [20100925]
- fix a buffer overflow in .ini parsing (it throws a glibc error on malloc)
- backport of conditional logging from 0.9.7-dev
- backport of backlog queue monitor from 0.9.7-dev (only Linux)
* 0.9.6.2 [20100915]
- fix a regression in virtual hosting mode
- fix pythonpath usage in --ini and --ini-paste
- new uwsgi packet var: UWSGI_CHDIR
* 0.9.6.1 [20100912]
- print the request uri during SIGPIPE or HARAKIRI
- added SIGUSR2 support (it will print the current running request, if available)
- protocol parsing optimization
- fixed --logto support
- new --eval option allows inline definition of WSGI script
- support for defining WSGI script in xml using CDATA
- allow --pp as --pythonpath shortcut
- various spooler optimizations and fixes
- added -O2 optimization by default
- added uwsgi.is_a_reload commodity function
- .ini file support fix
- SNMP agent fix
- support for subprocesses generated by master
- fix a regression in SCRIPT_NAME handling
- Haiku official support
- gcc 2.95 support
- dynamic app management optimizations
- export x-wsgiorg.uwsgi.version in WSGI env
*** august 2010 ***
* 0.9.6 [20100829]
- better handling of SCRIPT_NAME
- vacuum option for deleting unix sockets and pidfiles after usage
- advanced XML configuration
- new configuration systems: INI files and LDAP
- embedded HTTP server for development/testing
- better signal handling
- PSGI plugin improved
- usability fixes and new commodities options for root startup
- grunt processes (detached workers)
- preliminary integrated virtualhosting mode
- new option catch-exceptions can redirect python exceptions to your browser
- logging improvements (--logto and --logdate options)
- Full PEP 333 compliant usage of wsgi.file_wrapper
- re-initialize random seed after every fork() [security fix]
- fix Spooler's usage of stdin
- export WSGI environment in uwsgi.env (for doing evil things)
- logsize tracking (uwsgi.logsize) for future embedded log rotation
*** july 2010 ***
* 0.9.5.4 [20100706]
*** june 2010 ***
* 0.9.5.3 [20100628]
- fixed linux x86_64 compilation (sorry)
* 0.9.5.2 [20100626] *
- fixed a request parsing bug
- applied debian fixes
- fixed multiple interpreter sys.argv
- improved --chmod-socket
- fixed uid 0 SIGHUP
- updated nginx and apache modules
- updated PSGI, lua and example plugin
- fixed --pyargv with python 3.x
- improved plugin build system
*** may 2010 ***
* 0.9.5.1 [20100519] *
- fixed paste support
- added a new modifier (22)
- full support for configuration via environment variables
- nginx_string option in nginx module
- fix for harakiri without master
- backported unladen swallow support for 0.9.6-dev
- fixed address space limit detection via getrlimit()
- http body buffering implementation
- added --prio option (to set priority)
- added --post-limit to limit the size of uploads
- added --logto option to allow udp logging without daemonizing
- applied Gentoo's packagers fixes for build system
* 0.9.5 [20100501] *
- hook based request/modifier management
- plugin support via dlopen
- on-the-fly management flag
- integrated proxy
- logging via udp
- improved spooler for cron-like apps
- async support
- green thread platform (uGreen) on top of the async mode
- transparent Erlang integration
- embedded snmp agent
- nagios mode
- improved python 3.x support
- improved xml configuration
- new build system
- address space usage limiting
- lot of portability fixes
- lot of optimizations and code refactoring
*** april 2010 ***
* Fourth Maintenance release [20100427] *
- backported non-yielding app optimization from 0.9.5
- backported udp logging from 0.9.5
- backported uwsgi_error() from 0.9.5 (no more dumb perror())
- fix a rare (but possible) segmentation fault
- added --version
- updated apache2 module
*** march 2010 ***
* Third Maintenance release [20100310] *
- fix sendfile on 64bit
- include setup.py
*** february 2010 ***
* Maintenance release *
- better support for NetBSD
- threading fix for FreeBSD
- sendfile portability fixes
- new makefiles
- example app for testing static file serving
- fixes for ROCK_SOLID mode
*** january 2010 ***
- Integrated Spooler
- better error management
- long options
- clustering functions
- experimental lighttpd module
- official support for OpenBSD and OpenSolaris
- FastFuncs
- new functions for embedded module
- reliable harakiri
- better Makefiles
- python threads support in master process
- proper timeout handling in apache2 module
- endianess fixes all over the place
- paste support
- Django app for managing and monitoring the uWSGI server
- options for changin uid/gid and chrooting when run by root
- lot of bugfixes and optimizations
*** 20091129 Version 0.9.3 ***
- Nginx 0.7.x module
- configuration via python module
- support (non-standard) for Python 3.x
- Twisted client resource adapter
- graceful restart of worker processes and hot-plug substitution/upgrade of the uWSGI server
- shared memory area to share data between workers/processes
- Tomcat handler
- support for virtualenv
- tons of bugfixes and optimizations
*** 20090829 Version 0.9.2 ***
- TCP support
- configurable internal timeout (socket/poll)
- Cherokee handler
- code refactoring
- Makefiles
- customizable harakiri handler (put an harakiri(environ, start_response) function in your wsgi script)
- limit requests per worker
- a lot of bugfix and optimizations
+1 -1
View File
@@ -156,7 +156,7 @@ static int uwsgi_send_headers(request_rec *r, proxy_conn_rec *conn)
buf[0] = 0;
buf[1] = (uint8_t) (pktsize & 0xff);
buf[2] = (uint8_t) ((pktsize >> 8) & 0xff);
buf[0] = 0;
buf[3] = 0;
return uwsgi_send(conn, buf, headerlen, r);
}
+4
View File
@@ -0,0 +1,4 @@
#!/usr/bin/env ruby
cmd = File.expand_path "#{File.dirname(__FILE__)}/../ext/uwsgi/uwsgi.ruby"
exec(cmd, *ARGV)
+9 -3
View File
@@ -136,7 +136,7 @@ static struct uwsgi_alarm_instance *uwsgi_alarm_get_instance(char *name) {
}
static int uwsgi_alarm_log_add(char *alarms, char *regexp) {
static int uwsgi_alarm_log_add(char *alarms, char *regexp, int negate) {
struct uwsgi_alarm_log *old_ual = NULL, *ual = uwsgi.alarm_logs;
while (ual) {
@@ -148,6 +148,7 @@ static int uwsgi_alarm_log_add(char *alarms, char *regexp) {
if (uwsgi_regexp_build(regexp, &ual->pattern, &ual->pattern_extra)) {
return -1;
}
ual->negate = negate;
if (old_ual) {
old_ual->next = ual;
@@ -223,7 +224,7 @@ void uwsgi_alarms_init() {
*space = 0;
char *regexp = space + 1;
// here the log-alarm is created
if (uwsgi_alarm_log_add(line, regexp)) {
if (uwsgi_alarm_log_add(line, regexp, usl->custom)) {
uwsgi_log("invalid log-alarm: %s\n", usl->value);
exit(1);
}
@@ -239,7 +240,12 @@ void uwsgi_alarm_log_check(char *msg, size_t len) {
struct uwsgi_alarm_log *ual = uwsgi.alarm_logs;
while (ual) {
if (uwsgi_regexp_match(ual->pattern, ual->pattern_extra, msg, len) >= 0) {
uwsgi_alarm_log_run(ual, msg, len);
if (!ual->negate) {
uwsgi_alarm_log_run(ual, msg, len);
}
else {
break;
}
}
ual = ual->next;
}
-5
View File
@@ -189,11 +189,6 @@ int uwsgi_cache_del(char *key, uint16_t keylen, uint64_t index) {
uci->valsize = 0;
uwsgi.shared->cache_unused_stack_ptr++;
uwsgi.cache_unused_stack[uwsgi.shared->cache_unused_stack_ptr] = index;
// try to return to initial condition...
if (index == uwsgi.shared->cache_first_available_item - 1) {
uwsgi.shared->cache_first_available_item--;
//uwsgi_log("FACI: %llu STACK PTR: %llu\n", (unsigned long long) uwsgi.shared->cache_first_available_item, (unsigned long long) uwsgi.shared->cache_unused_stack_ptr);
}
ret = 0;
// relink collisioned entry
if (uci->prev) {
+51 -6
View File
@@ -6,7 +6,6 @@ a supervisor for multiple uWSGI instances
*/
#include "uwsgi.h"
#include <glob.h>
extern struct uwsgi_server uwsgi;
@@ -186,8 +185,24 @@ void uwsgi_imperial_monitor_directory(struct uwsgi_emperor_scanner *ues) {
while (c_ui) {
if (c_ui->scanner == ues) {
if (stat(c_ui->name, &st)) {
emperor_stop(c_ui);
if (c_ui->zerg) {
char *colon = strrchr(c_ui->name, ':');
if (!colon) {
emperor_stop(c_ui);
}
else {
char *filename = uwsgi_calloc(0xff);
memcpy(filename, c_ui->name, colon - c_ui->name);
if (stat(filename, &st)) {
emperor_stop(c_ui);
}
free(filename);
}
}
else {
if (stat(c_ui->name, &st)) {
emperor_stop(c_ui);
}
}
}
c_ui = c_ui->ui_next;
@@ -246,9 +261,25 @@ void uwsgi_imperial_monitor_glob(struct uwsgi_emperor_scanner *ues) {
while (c_ui) {
if (c_ui->scanner == ues) {
if (stat(c_ui->name, &st)) {
emperor_stop(c_ui);
}
if (c_ui->zerg) {
char *colon = strrchr(c_ui->name, ':');
if (!colon) {
emperor_stop(c_ui);
}
else {
char *filename = uwsgi_calloc(0xff);
memcpy(filename, c_ui->name, colon - c_ui->name);
if (stat(filename, &st)) {
emperor_stop(c_ui);
}
free(filename);
}
}
else {
if (stat(c_ui->name, &st)) {
emperor_stop(c_ui);
}
}
}
c_ui = c_ui->ui_next;
}
@@ -549,6 +580,10 @@ void emperor_add(struct uwsgi_emperor_scanner *ues, char *name, time_t born, cha
}
}
if (n_ui->zerg) {
uwsgi.emperor_broodlord_num++;
}
// TODO pre-start hook
// a new uWSGI instance will start
@@ -602,6 +637,16 @@ void emperor_add(struct uwsgi_emperor_scanner *ues, char *name, time_t born, cha
}
free(uef);
// add UWSGI_BROODLORD_NUM
if (n_ui->zerg) {
uef = uwsgi_num2str(uwsgi.emperor_broodlord_num);
if (setenv("UWSGI_BROODLORD_NUM", uef, 1)) {
uwsgi_error("setenv()");
exit(1);
}
free(uef);
}
if (n_ui->use_config) {
uef = uwsgi_num2str(n_ui->pipe_config[1]);
if (setenv("UWSGI_EMPEROR_FD_CONFIG", uef, 1)) {
+6 -1
View File
@@ -41,6 +41,10 @@ struct uwsgi_gateway *register_gateway(char *name, void (*loop) (int, void *), v
return ug;
}
static void gateway_brutal_end() {
_exit(UWSGI_END_CODE);
}
void gateway_respawn(int id) {
pid_t gw_pid;
@@ -65,6 +69,7 @@ void gateway_respawn(int id) {
}
#endif
uwsgi.mypid = getpid();
atexit(gateway_brutal_end);
signal(SIGALRM, SIG_IGN);
signal(SIGHUP, SIG_IGN);
signal(SIGINT, end_me);
@@ -77,7 +82,7 @@ void gateway_respawn(int id) {
ug->loop(id, ug->data);
// never here !!! (i hope)
exit(1);
_exit(1);
}
ug->pid = gw_pid;
+28 -2
View File
@@ -64,6 +64,12 @@ int uwsgi_pthread_robust_mutexes_enabled = 1;
#define UWSGI_RWLOCK_SIZE sizeof(pthread_rwlock_t)
#endif
#ifndef PTHREAD_PRIO_INHERIT
int pthread_mutexattr_setprotocol (pthread_mutexattr_t *__attr,
int __protocol);
#define PTHREAD_PRIO_INHERIT 1
#endif
// REMEMBER lock must contains space for both pthread_mutex_t and pthread_mutexattr_t !!!
struct uwsgi_lock_item *uwsgi_lock_fast_init(char *id) {
@@ -85,8 +91,16 @@ retry:
}
#ifdef EOWNERDEAD
#ifndef PTHREAD_MUTEX_ROBUST
#define PTHREAD_MUTEX_ROBUST PTHREAD_MUTEX_ROBUST_NP
#endif
if (pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT)) {
uwsgi_log("unable to set PTHREAD_PRIO_INHERIT\n");
exit(1);
}
if (uwsgi_pthread_robust_mutexes_enabled) {
if (pthread_mutexattr_setrobust_np(&attr, PTHREAD_MUTEX_ROBUST_NP)) {
if (pthread_mutexattr_setrobust_np(&attr, PTHREAD_MUTEX_ROBUST)) {
uwsgi_log("unable to make the mutex 'robust'\n");
exit(1);
}
@@ -464,7 +478,9 @@ void uwsgi_lock_ipcsem(struct uwsgi_lock_item *uli) {
memcpy(&semid, uli->lock_ptr, sizeof(int));
retry:
if (semop(semid, &sb, 1)) {
if (errno == EINTR) goto retry;
uwsgi_error("semop()");
}
}
@@ -479,7 +495,9 @@ void uwsgi_unlock_ipcsem(struct uwsgi_lock_item *uli) {
memcpy(&semid, uli->lock_ptr, sizeof(int));
retry:
if (semop(semid, &sb, 1)) {
if (errno == EINTR) goto retry;
uwsgi_error("semop()");
}
@@ -560,8 +578,10 @@ void uwsgi_setup_locking() {
uwsgi.lock_ops.rwunlock = uwsgi_rwunlock_ipcsem;
uwsgi.lock_size = 8;
uwsgi.rwlock_size = 8;
return;
goto ready;
}
uwsgi_log("unable to find lock engine \"%s\"\n", uwsgi.lock_engine);
exit(1);
}
uwsgi_log_initial("lock engine: %s\n", UWSGI_LOCK_ENGINE_NAME);
@@ -582,6 +602,7 @@ void uwsgi_setup_locking() {
// application generic lock
int i;
ready:
uwsgi.user_lock = uwsgi_malloc(sizeof(void *) * (uwsgi.locks + 1));
for (i = 0; i < uwsgi.locks + 1; i++) {
uwsgi.user_lock[i] = uwsgi_lock_init(uwsgi_concat2("user ", uwsgi_num2str(i)));
@@ -612,6 +633,11 @@ void uwsgi_setup_locking() {
uwsgi.cron_table_lock = uwsgi_lock_init("cron");
}
if (uwsgi.use_thunder_lock) {
// process shared thunder lock
uwsgi.the_thunder_lock = uwsgi_lock_init("thunder");
}
uwsgi.rpc_table_lock = uwsgi_lock_init("rpc");
}
+140 -11
View File
@@ -931,38 +931,38 @@ void uwsgi_build_log_format(char *format) {
}
ssize_t uwsgi_lf_status(struct wsgi_request *wsgi_req, char **buf) {
static ssize_t uwsgi_lf_status(struct wsgi_request *wsgi_req, char **buf) {
*buf = uwsgi_num2str(wsgi_req->status);
return strlen(*buf);
}
ssize_t uwsgi_lf_rsize(struct wsgi_request *wsgi_req, char **buf) {
static ssize_t uwsgi_lf_rsize(struct wsgi_request *wsgi_req, char **buf) {
*buf = uwsgi_num2str(wsgi_req->response_size);
return strlen(*buf);
}
ssize_t uwsgi_lf_hsize(struct wsgi_request *wsgi_req, char **buf) {
static ssize_t uwsgi_lf_hsize(struct wsgi_request *wsgi_req, char **buf) {
*buf = uwsgi_num2str(wsgi_req->headers_size);
return strlen(*buf);
}
ssize_t uwsgi_lf_size(struct wsgi_request *wsgi_req, char **buf) {
static ssize_t uwsgi_lf_size(struct wsgi_request *wsgi_req, char **buf) {
*buf = uwsgi_num2str(wsgi_req->headers_size+wsgi_req->response_size);
return strlen(*buf);
}
ssize_t uwsgi_lf_cl(struct wsgi_request *wsgi_req, char **buf) {
static ssize_t uwsgi_lf_cl(struct wsgi_request *wsgi_req, char **buf) {
*buf = uwsgi_num2str(wsgi_req->post_cl);
return strlen(*buf);
}
ssize_t uwsgi_lf_epoch(struct wsgi_request * wsgi_req, char **buf) {
static ssize_t uwsgi_lf_epoch(struct wsgi_request * wsgi_req, char **buf) {
*buf = uwsgi_num2str(uwsgi_now());
return strlen(*buf);
}
ssize_t uwsgi_lf_ctime(struct wsgi_request * wsgi_req, char **buf) {
static ssize_t uwsgi_lf_ctime(struct wsgi_request * wsgi_req, char **buf) {
*buf = uwsgi_malloc(26);
#ifdef __sun__
ctime_r((const time_t *) &wsgi_req->start_of_request_in_sec, *buf, 26);
@@ -972,12 +972,12 @@ ssize_t uwsgi_lf_ctime(struct wsgi_request * wsgi_req, char **buf) {
return 24;
}
ssize_t uwsgi_lf_time(struct wsgi_request * wsgi_req, char **buf) {
static ssize_t uwsgi_lf_time(struct wsgi_request * wsgi_req, char **buf) {
*buf = uwsgi_num2str(wsgi_req->start_of_request / 1000000);
return strlen(*buf);
}
ssize_t uwsgi_lf_ltime(struct wsgi_request * wsgi_req, char **buf) {
static ssize_t uwsgi_lf_ltime(struct wsgi_request * wsgi_req, char **buf) {
*buf = uwsgi_malloc(64);
time_t now = wsgi_req->start_of_request / 1000000;
size_t ret = strftime(*buf, 64, "%d/%b/%Y:%H:%M:%S %z", localtime(&now));
@@ -990,16 +990,80 @@ ssize_t uwsgi_lf_ltime(struct wsgi_request * wsgi_req, char **buf) {
ssize_t uwsgi_lf_micros(struct wsgi_request * wsgi_req, char **buf) {
static ssize_t uwsgi_lf_micros(struct wsgi_request * wsgi_req, char **buf) {
*buf = uwsgi_num2str(wsgi_req->end_of_request - wsgi_req->start_of_request);
return strlen(*buf);
}
ssize_t uwsgi_lf_msecs(struct wsgi_request * wsgi_req, char **buf) {
static ssize_t uwsgi_lf_msecs(struct wsgi_request * wsgi_req, char **buf) {
*buf = uwsgi_num2str((wsgi_req->end_of_request - wsgi_req->start_of_request) / 1000);
return strlen(*buf);
}
static ssize_t uwsgi_lf_pid(struct wsgi_request * wsgi_req, char **buf) {
*buf = uwsgi_num2str(uwsgi.mypid);
return strlen(*buf);
}
static ssize_t uwsgi_lf_wid(struct wsgi_request * wsgi_req, char **buf) {
*buf = uwsgi_num2str(uwsgi.mywid);
return strlen(*buf);
}
static ssize_t uwsgi_lf_switches(struct wsgi_request * wsgi_req, char **buf) {
*buf = uwsgi_num2str(wsgi_req->switches);
return strlen(*buf);
}
static ssize_t uwsgi_lf_vars(struct wsgi_request * wsgi_req, char **buf) {
*buf = uwsgi_num2str(wsgi_req->var_cnt);
return strlen(*buf);
}
static ssize_t uwsgi_lf_core(struct wsgi_request * wsgi_req, char **buf) {
*buf = uwsgi_num2str(wsgi_req->async_id);
return strlen(*buf);
}
static ssize_t uwsgi_lf_vsz(struct wsgi_request * wsgi_req, char **buf) {
*buf = uwsgi_num2str(uwsgi.workers[uwsgi.mywid].vsz_size);
return strlen(*buf);
}
static ssize_t uwsgi_lf_rss(struct wsgi_request * wsgi_req, char **buf) {
*buf = uwsgi_num2str(uwsgi.workers[uwsgi.mywid].rss_size);
return strlen(*buf);
}
static ssize_t uwsgi_lf_vszM(struct wsgi_request * wsgi_req, char **buf) {
*buf = uwsgi_num2str(uwsgi.workers[uwsgi.mywid].vsz_size / 1024 / 1024);
return strlen(*buf);
}
static ssize_t uwsgi_lf_rssM(struct wsgi_request * wsgi_req, char **buf) {
*buf = uwsgi_num2str(uwsgi.workers[uwsgi.mywid].rss_size / 1024 / 1024);
return strlen(*buf);
}
static ssize_t uwsgi_lf_pktsize(struct wsgi_request * wsgi_req, char **buf) {
*buf = uwsgi_num2str(wsgi_req->uh.pktsize);
return strlen(*buf);
}
static ssize_t uwsgi_lf_modifier1(struct wsgi_request * wsgi_req, char **buf) {
*buf = uwsgi_num2str(wsgi_req->uh.modifier1);
return strlen(*buf);
}
static ssize_t uwsgi_lf_modifier2(struct wsgi_request * wsgi_req, char **buf) {
*buf = uwsgi_num2str(wsgi_req->uh.modifier2);
return strlen(*buf);
}
static ssize_t uwsgi_lf_headers(struct wsgi_request * wsgi_req, char **buf) {
*buf = uwsgi_num2str(wsgi_req->header_cnt);
return strlen(*buf);
}
void uwsgi_add_logchunk(int variable, int pos, char *ptr, size_t len) {
@@ -1121,6 +1185,71 @@ void uwsgi_add_logchunk(int variable, int pos, char *ptr, size_t len) {
logchunk->func = uwsgi_lf_epoch;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "pid", 3)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_pid;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "wid", 3)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_wid;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "switches", 8)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_switches;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "vars", 4)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_vars;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "core", 4)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_core;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "vsz", 3)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_vsz;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "rss", 3)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_rss;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "vszM", 4)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_vszM;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "rssM", 4)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_rssM;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "pktsize", 7)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_pktsize;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "modifier1", 9)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_modifier1;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "modifier2", 9)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_modifier2;
logchunk->free = 1;
}
else if (!uwsgi_strncmp(ptr, len, "headers", 7)) {
logchunk->type = 3;
logchunk->func = uwsgi_lf_headers;
logchunk->free = 1;
}
// logvar
else {
logchunk->type = 2;
+2 -2
View File
@@ -738,7 +738,7 @@ int master_loop(char **argv, char **environ) {
}
if (uwsgi.requested_stats_pushers) {
if (uwsgi.stats_pusher_instances) {
if (!uwsgi_thread_new(uwsgi_stats_pusher_loop)) {
uwsgi_log("!!! unable to spawn stats pusher thread !!!\n");
exit(1);
@@ -1461,7 +1461,7 @@ health_cycle:
continue;
#endif
if (uwsgi.emperor_pid >= 0) {
if (uwsgi.emperor_pid >= 0 && diedpid == uwsgi.emperor_pid) {
uwsgi_log_verbose("!!! Emperor died !!!\n");
uwsgi_emperor_start();
continue;
+2 -1
View File
@@ -508,7 +508,8 @@ int uwsgi_respawn_worker(int wid) {
uwsgi.workers[wid].cheaped = 0;
uwsgi.workers[wid].busy = 0;
uwsgi.workers[wid].suspended = 0;
// SUSPENSION is managed by the user, not the master...
//uwsgi.workers[wid].suspended = 0;
uwsgi.workers[wid].sig = 0;
// this is required for various checks
+3 -3
View File
@@ -405,12 +405,12 @@ void uwsgi_setup_mules_and_farms() {
uwsgi.mules = (struct uwsgi_mule *) uwsgi_calloc_shared(sizeof(struct uwsgi_mule) * uwsgi.mules_cnt);
create_signal_pipe(uwsgi.shared->mule_signal_pipe);
create_signal_pipe(uwsgi.shared->mule_queue_pipe);
create_msg_pipe(uwsgi.shared->mule_queue_pipe, uwsgi.mule_msg_size);
for (i = 0; i < uwsgi.mules_cnt; i++) {
// create the socket pipe
create_signal_pipe(uwsgi.mules[i].signal_pipe);
create_signal_pipe(uwsgi.mules[i].queue_pipe);
create_msg_pipe(uwsgi.mules[i].queue_pipe, uwsgi.mule_msg_size);
uwsgi.mules[i].id = i + 1;
@@ -439,7 +439,7 @@ void uwsgi_setup_mules_and_farms() {
// create the socket pipe
create_signal_pipe(uwsgi.farms[i].signal_pipe);
create_signal_pipe(uwsgi.farms[i].queue_pipe);
create_msg_pipe(uwsgi.farms[i].queue_pipe, uwsgi.mule_msg_size);
char *p = strtok(mules_list, ",");
while (p != NULL) {
+39 -30
View File
@@ -62,40 +62,49 @@ int uwsgi_regexp_ovector(pcre * pattern, pcre_extra * pattern_extra) {
char *uwsgi_regexp_apply_ovec(char *src, int src_n, char *dst, int dst_n, int *ovector, int n) {
int i;
int dollar = 0;
int i;
int dollar = 0;
char *res = uwsgi_malloc(dst_n + (src_n * n) + 1);
char *ptr = res;
size_t dollars = n;
for (i = 0; i < dst_n; i++) {
if (dollar) {
if (isdigit((int) dst[i])) {
int pos = (dst[i] - 48);
if (pos <= n) {
pos = pos * 2;
memcpy(ptr, src + ovector[pos], ovector[pos + 1] - ovector[pos]);
ptr += ovector[pos + 1] - ovector[pos];
}
}
else {
*ptr++ = dst[i];
}
dollar = 0;
}
else {
if (dst[i] == '$') {
dollar = 1;
}
else {
*ptr++ = dst[i];
}
}
}
for(i=0;i<dst_n;i++) {
if (dst[i] == '$') {
dollars++;
}
}
*ptr++ = 0;
char *res = uwsgi_malloc(dst_n + (src_n * dollars) + 1);
char *ptr = res;
return res;
for (i = 0; i < dst_n; i++) {
if (dollar) {
if (isdigit((int) dst[i])) {
int pos = (dst[i] - 48);
if (pos <= n) {
pos = pos * 2;
memcpy(ptr, src + ovector[pos], ovector[pos + 1] - ovector[pos]);
ptr += ovector[pos + 1] - ovector[pos];
}
}
else {
*ptr++ = '$';
*ptr++ = dst[i];
}
dollar = 0;
}
else {
if (dst[i] == '$') {
dollar = 1;
}
else {
*ptr++ = dst[i];
}
}
}
*ptr++ = 0;
return res;
}
#endif
+16 -8
View File
@@ -373,7 +373,7 @@ struct uwsgi_stats_pusher *uwsgi_stats_pusher_get(char *name) {
return usp;
}
void uwsgi_stats_pusher_add(struct uwsgi_stats_pusher *pusher, char *arg) {
struct uwsgi_stats_pusher_instance * uwsgi_stats_pusher_add(struct uwsgi_stats_pusher *pusher, char *arg) {
struct uwsgi_stats_pusher_instance *old_uspi = NULL, *uspi = uwsgi.stats_pusher_instances;
while (uspi) {
old_uspi = uspi;
@@ -389,6 +389,8 @@ void uwsgi_stats_pusher_add(struct uwsgi_stats_pusher *pusher, char *arg) {
else {
uwsgi.stats_pusher_instances = uspi;
}
return uspi;
}
void uwsgi_stats_pusher_loop(struct uwsgi_thread *ut) {
@@ -413,12 +415,16 @@ void uwsgi_stats_pusher_loop(struct uwsgi_thread *ut) {
while (uspi) {
int delta = uspi->freq ? uspi->freq : uwsgi.stats_pusher_default_freq;
if ((uspi->last_run + delta) <= now) {
if (!us) {
us = uwsgi_master_generate_stats();
if (!us)
goto next;
if (uspi->raw) {
uspi->pusher->func(uspi, now, NULL, 0);
}
else {
if (!us) {
us = uwsgi_master_generate_stats();
if (!us) goto next;
}
uspi->pusher->func(uspi, now, us->base, us->pos);
}
uspi->pusher->func(uspi, us->base, us->pos);
uspi->last_run = now;
}
next:
@@ -456,7 +462,7 @@ void uwsgi_stats_pusher_setup() {
}
}
void uwsgi_register_stats_pusher(char *name, void (*func) (struct uwsgi_stats_pusher_instance *, char *, size_t)) {
struct uwsgi_stats_pusher *uwsgi_register_stats_pusher(char *name, void (*func) (struct uwsgi_stats_pusher_instance *, time_t, char *, size_t)) {
struct uwsgi_stats_pusher *pusher = uwsgi.stats_pushers, *old_pusher = NULL;
@@ -475,6 +481,8 @@ void uwsgi_register_stats_pusher(char *name, void (*func) (struct uwsgi_stats_pu
else {
uwsgi.stats_pushers = pusher;
}
return pusher;
}
struct uwsgi_stats_pusher_file_conf {
@@ -483,7 +491,7 @@ struct uwsgi_stats_pusher_file_conf {
char *separator;
};
void uwsgi_stats_pusher_file(struct uwsgi_stats_pusher_instance *uspi, char *json, size_t json_len) {
void uwsgi_stats_pusher_file(struct uwsgi_stats_pusher_instance *uspi, time_t now, char *json, size_t json_len) {
struct uwsgi_stats_pusher_file_conf *uspic = (struct uwsgi_stats_pusher_file_conf *) uspi->data;
if (!uspi->configured) {
uspic = uwsgi_calloc(sizeof(struct uwsgi_stats_pusher_file_conf));
+73
View File
@@ -2032,6 +2032,24 @@ int uwsgi_logic_opt_for(char *key, char *value) {
return 1;
}
int uwsgi_logic_opt_for_glob(char *key, char *value) {
glob_t g;
int i;
if (glob(uwsgi.logic_opt_data, GLOB_MARK | GLOB_NOCHECK, NULL, &g)) {
uwsgi_error("uwsgi_logic_opt_for_glob()");
return 0;
}
for (i = 0; i < (int) g.gl_pathc; i++) {
add_exported_option(key, uwsgi_substitute(value, "%(_)", g.gl_pathv[i]), 0);
}
globfree(&g);
return 1;
}
void add_exported_option(char *key, char *value, int configured) {
struct uwsgi_string_list *blacklist = uwsgi.blacklist;
@@ -5119,3 +5137,58 @@ void uwsgi_close_all_fds(void) {
}
}
/*
even if it is marked as non-blocking, so not use in request plugins as it uses poll() and not the hooks
*/
int uwsgi_write_nb(int fd, char *buf, size_t remains, int timeout) {
char *ptr = buf;
while(remains > 0) {
int ret = uwsgi_waitfd_write(fd, timeout);
if (ret > 0) {
ssize_t len = write(fd, ptr, remains);
if (len <= 0) {
return -1;
}
ptr += len;
remains -= len;
continue;
}
return -1;
}
return 0;
}
// create a message pipe
void create_msg_pipe(int *fd, int bufsize) {
#if defined(SOCK_SEQPACKET) && defined(__linux__)
if (socketpair(AF_UNIX, SOCK_SEQPACKET, 0, fd)) {
#else
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, fd)) {
#endif
uwsgi_error("create_msg_pipe()/socketpair()");
exit(1);
}
uwsgi_socket_nb(fd[0]);
uwsgi_socket_nb(fd[1]);
if (bufsize) {
if (setsockopt(fd[0], SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(int))) {
uwsgi_error("create_msg_pipe()/setsockopt()");
}
if (setsockopt(fd[0], SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(int))) {
uwsgi_error("create_msg_pipe()/setsockopt()");
}
if (setsockopt(fd[1], SOL_SOCKET, SO_SNDBUF, &bufsize, sizeof(int))) {
uwsgi_error("create_msg_pipe()/setsockopt()");
}
if (setsockopt(fd[1], SOL_SOCKET, SO_RCVBUF, &bufsize, sizeof(int))) {
uwsgi_error("create_msg_pipe()/setsockopt()");
}
}
}
+24 -3
View File
@@ -38,6 +38,8 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"socket", required_argument, 's', "bind to the specified UNIX/TCP socket using default protocol", uwsgi_opt_add_socket, NULL, 0},
{"uwsgi-socket", required_argument, 's', "bind to the specified UNIX/TCP socket using uwsgi protocol", uwsgi_opt_add_socket, "uwsgi", 0},
{"http-socket", required_argument, 0, "bind to the specified UNIX/TCP socket using HTTP protocol", uwsgi_opt_add_socket, "http", 0},
{"http-socket-modifier1", required_argument, 0, "force the specified modifier1 when using HTTP protocol", uwsgi_opt_set_64bit, &uwsgi.http_modifier1, 0},
{"http-socket-modifier2", required_argument, 0, "force the specified modifier2 when using HTTP protocol", uwsgi_opt_set_64bit, &uwsgi.http_modifier2, 0},
{"fastcgi-socket", required_argument, 0, "bind to the specified UNIX/TCP socket using FastCGI protocol", uwsgi_opt_add_socket, "fastcgi", 0},
{"protocol", required_argument, 0, "force the specified protocol for default sockets", uwsgi_opt_set_str, &uwsgi.protocol, 0},
{"socket-protocol", required_argument, 0, "force the specified protocol for default sockets", uwsgi_opt_set_str, &uwsgi.protocol, 0},
@@ -45,12 +47,13 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"undeferred-shared-socket", required_argument, 0, "create a shared sacket for advanced jailing or ipc (undeferred mode)", uwsgi_opt_add_shared_socket, NULL, 0},
{"processes", required_argument, 'p', "spawn the specified number of workers/processes", uwsgi_opt_set_int, &uwsgi.numproc, 0},
{"workers", required_argument, 'p', "spawn the specified number of workers/processes", uwsgi_opt_set_int, &uwsgi.numproc, 0},
{"thunder-lock", no_argument, 0, "serialize accept() usage (if possibie)", uwsgi_opt_true, &uwsgi.use_thunder_lock, 0},
{"harakiri", required_argument, 't', "set harakiri timeout", uwsgi_opt_set_dyn, (void *) UWSGI_OPTION_HARAKIRI, 0},
{"harakiri-verbose", no_argument, 0, "enable verbose mode for harakiri", uwsgi_opt_true, &uwsgi.harakiri_verbose, 0},
{"harakiri-no-arh", no_argument, 0, "do not enable harakiri during after-request-hook", uwsgi_opt_true, &uwsgi.harakiri_no_arh, 0},
{"no-harakiri-arh", no_argument, 0, "do not enable harakiri during after-request-hook", uwsgi_opt_true, &uwsgi.harakiri_no_arh, 0},
{"no-harakiri-after-req-hook", no_argument, 0, "do not enable harakiri during after-request-hook", uwsgi_opt_true, &uwsgi.harakiri_no_arh, 0},
{"backtrace-depth", no_argument, 0, "set backtrace depth", uwsgi_opt_set_int, &uwsgi.backtrace_depth, 0},
{"backtrace-depth", required_argument, 0, "set backtrace depth", uwsgi_opt_set_int, &uwsgi.backtrace_depth, 0},
{"mule-harakiri", required_argument, 0, "set harakiri timeout for mule tasks", uwsgi_opt_set_dyn, (void *) UWSGI_OPTION_MULE_HARAKIRI, 0},
#ifdef UWSGI_XML
{"xmlconfig", required_argument, 'x', "load config from xml file", uwsgi_opt_load_xml, NULL, UWSGI_OPT_IMMEDIATE},
@@ -63,6 +66,7 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"declare-option", required_argument, 0, "declare a new uWSGI custom option", uwsgi_opt_add_custom_option, NULL, UWSGI_OPT_IMMEDIATE},
{"for", required_argument, 0, "(opt logic) for cycle", uwsgi_opt_logic, (void *) uwsgi_logic_opt_for, UWSGI_OPT_IMMEDIATE},
{"for-glob", required_argument, 0, "(opt logic) for cycle (expand glob)", uwsgi_opt_logic, (void *) uwsgi_logic_opt_for_glob, UWSGI_OPT_IMMEDIATE},
{"endfor", optional_argument, 0, "(opt logic) end for cycle", uwsgi_opt_noop, NULL, UWSGI_OPT_IMMEDIATE},
{"if-opt", required_argument, 0, "(opt logic) check for option", uwsgi_opt_logic, (void *) uwsgi_logic_opt_if_opt, UWSGI_OPT_IMMEDIATE},
@@ -204,6 +208,7 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"mule", optional_argument, 0, "add a mule", uwsgi_opt_add_mule, NULL, UWSGI_OPT_MASTER},
{"mules", required_argument, 0, "add the specified number of mules", uwsgi_opt_add_mules, NULL, UWSGI_OPT_MASTER},
{"farm", required_argument, 0, "add a mule farm", uwsgi_opt_add_farm, NULL, UWSGI_OPT_MASTER},
{"mule-msg-size", optional_argument, 0, "set mule message buffer size", uwsgi_opt_set_int, &uwsgi.mule_msg_size, UWSGI_OPT_MASTER},
{"signal", required_argument, 0, "send a uwsgi signal to a server", uwsgi_opt_signal, NULL, UWSGI_OPT_IMMEDIATE},
{"signal-bufsize", required_argument, 0, "set buffer size for signal queue", uwsgi_opt_set_int, &uwsgi.signal_bufsize, 0},
@@ -379,6 +384,9 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"alarm", required_argument, 0, "create a new alarm, syntax: <alarm> <plugin:args>", uwsgi_opt_add_string_list, &uwsgi.alarm_list, UWSGI_OPT_MASTER | UWSGI_OPT_LOG_MASTER},
{"alarm-freq", required_argument, 0, "tune the anti-loop alam system (default 3 seconds)", uwsgi_opt_set_int, &uwsgi.alarm_freq, 0},
{"log-alarm", required_argument, 0, "raise the specified alarm when a log line matches the specified regexp, syntax: <alarm>[,alarm...] <regexp>", uwsgi_opt_add_string_list, &uwsgi.alarm_logs_list, UWSGI_OPT_MASTER | UWSGI_OPT_LOG_MASTER},
{"alarm-log", required_argument, 0, "raise the specified alarm when a log line matches the specified regexp, syntax: <alarm>[,alarm...] <regexp>", uwsgi_opt_add_string_list, &uwsgi.alarm_logs_list, UWSGI_OPT_MASTER | UWSGI_OPT_LOG_MASTER},
{"not-log-alarm", required_argument, 0, "skip the specified alarm when a log line matches the specified regexp, syntax: <alarm>[,alarm...] <regexp>", uwsgi_opt_add_string_list_custom, &uwsgi.alarm_logs_list, UWSGI_OPT_MASTER | UWSGI_OPT_LOG_MASTER},
{"not-alarm-log", required_argument, 0, "skip the specified alarm when a log line matches the specified regexp, syntax: <alarm>[,alarm...] <regexp>", uwsgi_opt_add_string_list_custom, &uwsgi.alarm_logs_list, UWSGI_OPT_MASTER | UWSGI_OPT_LOG_MASTER},
{"alarm-list", no_argument, 0, "list enabled alarms", uwsgi_opt_true, &uwsgi.alarms_list, 0},
{"alarms-list", no_argument, 0, "list enabled alarms", uwsgi_opt_true, &uwsgi.alarms_list, 0},
#endif
@@ -1662,6 +1670,14 @@ int main(int argc, char *argv[], char *envp[]) {
struct utsname uuts;
// signal mask is inherited, and sme process manager could make a real mess...
sigset_t smask;
sigfillset(&smask);
if (sigprocmask(SIG_UNBLOCK, &smask, NULL)) {
uwsgi_error("sigprocmask()");
}
signal(SIGCHLD, SIG_DFL);
signal(SIGSEGV, uwsgi_segfault);
signal(SIGFPE, uwsgi_fpe);
signal(SIGHUP, SIG_IGN);
@@ -2329,9 +2345,9 @@ int uwsgi_start(void *v_argv) {
#endif
#ifdef UWSGI_UDP
if (!uwsgi.sockets && !ushared->gateways_cnt && !uwsgi.no_server && !uwsgi.udp_socket && !uwsgi.emperor && !uwsgi.command_mode) {
if (!uwsgi.sockets && !ushared->gateways_cnt && !uwsgi.no_server && !uwsgi.udp_socket && !uwsgi.emperor && !uwsgi.command_mode && !uwsgi.daemons_cnt) {
#else
if (!uwsgi.sockets && !ushared->gateways_cnt && !uwsgi.no_server && !uwsgi.emperor && !uwsgi.command_mode) {
if (!uwsgi.sockets && !ushared->gateways_cnt && !uwsgi.no_server && !uwsgi.emperor && !uwsgi.command_mode && !uwsgi.daemons_cnt) {
#endif
uwsgi_log("The -s/--socket option is missing and stdin is not a socket.\n");
exit(1);
@@ -3319,6 +3335,11 @@ void uwsgi_opt_add_addr_list(char *opt, char *value, void *list) {
usl->custom_ptr = value;
}
void uwsgi_opt_add_string_list_custom(char *opt, char *value, void *list) {
struct uwsgi_string_list **ptr = (struct uwsgi_string_list **) list;
struct uwsgi_string_list *usl = uwsgi_string_new_list(ptr, value);
usl->custom = 1;
}
#ifdef UWSGI_PCRE
void uwsgi_opt_add_regexp_list(char *opt, char *value, void *list) {
+15
View File
@@ -0,0 +1,15 @@
require 'net/http'
Net::HTTP.start("uwsgi.it") do |http|
resp = http.get("/install")
open("install.sh", "wb") do |file|
file.write(resp.body)
end
end
system("bash install.sh rack #{Dir.pwd}/uwsgi.ruby")
open("Makefile", "w") do |file|
file.write("all:\n")
file.write("\t\n")
end
+15 -1
View File
@@ -1,5 +1,6 @@
#include "../../uwsgi.h"
#include <gloox/client.h>
#include <gloox/error.h>
#include <gloox/message.h>
#include <gloox/connectionlistener.h>
#include <gloox/connectiontcpclient.h>
@@ -51,11 +52,14 @@ class Jabbo : public ConnectionListener{
event_queue_add_fd_read(u_thread->queue, fd);
event_queue_add_fd_read(u_thread->queue, u_thread->pipe[1]);
u_connected = 1;
uwsgi_log("[uwsgi-xmpp] connected to the XMPP server\n");
}
virtual void onDisconnect(ConnectionError e) {
uwsgi_log("[uwsgi-xmpp] trying reconnect to the XMPP server...\n");
if (u_connected) {
event_queue_del_fd(u_thread->queue, fd, event_queue_read());
// no need to remove it as it is already closed...
//event_queue_del_fd(u_thread->queue, fd, event_queue_read());
event_queue_del_fd(u_thread->queue, u_thread->pipe[1], event_queue_read());
}
sleep(1);
@@ -64,6 +68,16 @@ class Jabbo : public ConnectionListener{
fd = static_cast<ConnectionTCPClient*>( client->connectionImpl() )->socket();
}
virtual void onResourceBindError(const Error *error) {
uwsgi_log("[uwsgi-xmpp] onResourceBindError(): %s\n", error->text().c_str());
client->disconnect();
}
virtual void onSessionCreateError(const Error *error) {
uwsgi_log("[uwsgi-xmpp] onSessionCreateError(): %s\n", error->text().c_str());
client->disconnect();
}
virtual bool onTLSConnect(const CertInfo& info) {
return true;
}
+105 -50
View File
@@ -1,4 +1,10 @@
#include "../../uwsgi.h"
#include <uwsgi.h>
/*
Author: Łukasz Mierzwa
*/
extern struct uwsgi_server uwsgi;
@@ -18,14 +24,19 @@ struct uwsgi_carbon {
int no_workers;
unsigned long long *last_busyness_values;
unsigned long long *current_busyness_values;
int *was_busy;
int need_retry;
time_t last_update;
time_t next_retry;
int max_retries;
int retry_delay;
char *root_node;
char *hostname_dot_replacement;
char *hostname;
struct uwsgi_stats_pusher *pusher;
} u_carbon;
struct uwsgi_option carbon_options[] = {
static struct uwsgi_option carbon_options[] = {
{"carbon", required_argument, 0, "push statistics to the specified carbon server", uwsgi_opt_add_string_list, &u_carbon.servers, UWSGI_OPT_MASTER},
{"carbon-timeout", required_argument, 0, "set carbon connection timeout in seconds (default 3)", uwsgi_opt_set_int, &u_carbon.timeout, 0},
{"carbon-freq", required_argument, 0, "set carbon push frequency in seconds (default 60)", uwsgi_opt_set_int, &u_carbon.freq, 0},
@@ -33,12 +44,13 @@ struct uwsgi_option carbon_options[] = {
{"carbon-no-workers", no_argument, 0, "disable generation of single worker metrics", uwsgi_opt_true, &u_carbon.no_workers, 0},
{"carbon-max-retry", required_argument, 0, "set maximum number of retries in case of connection errors (default 1)", uwsgi_opt_set_int, &u_carbon.max_retries, 0},
{"carbon-retry-delay", required_argument, 0, "set connection retry delay in seconds (default 7)", uwsgi_opt_set_int, &u_carbon.retry_delay, 0},
{"carbon-root", required_argument, 0, "set carbon metrics root node (default 'uwsgi')", uwsgi_opt_set_str, &u_carbon.root_node, 0},
{"carbon-hostname-dots", required_argument, 0, "set char to use as a replacement for dots in hostname (dots are not replaced by default)", uwsgi_opt_set_str, &u_carbon.hostname_dot_replacement, 0},
{0, 0, 0, 0, 0, 0, 0},
};
void carbon_post_init() {
static void carbon_post_init() {
int i;
struct uwsgi_string_list *usl = u_carbon.servers;
@@ -59,6 +71,11 @@ void carbon_post_init() {
usl = usl->next;
}
if (!u_carbon.root_node) u_carbon.root_node = "uwsgi.";
if (strlen(u_carbon.root_node) && !uwsgi_endswith(u_carbon.root_node, ".")) {
u_carbon.root_node = uwsgi_concat2(u_carbon.root_node, ".");
}
if (u_carbon.freq < 1) u_carbon.freq = 60;
if (u_carbon.timeout < 1) u_carbon.timeout = 3;
if (u_carbon.max_retries <= 0) u_carbon.max_retries = 1;
@@ -71,22 +88,39 @@ void carbon_post_init() {
}
}
u_carbon.hostname = uwsgi_str(uwsgi.hostname);
if (u_carbon.hostname_dot_replacement) {
for(i=0;i<(int)strlen(u_carbon.hostname);i++) {
if (u_carbon.hostname[i] == '.') u_carbon.hostname[i] = u_carbon.hostname_dot_replacement[0];
}
}
if (!u_carbon.last_busyness_values) {
u_carbon.last_busyness_values = uwsgi_calloc(sizeof(unsigned long long) * uwsgi.numproc);
}
if (!u_carbon.current_busyness_values) {
u_carbon.current_busyness_values = uwsgi_calloc(sizeof(unsigned long long) * uwsgi.numproc);
}
if (!u_carbon.was_busy) {
u_carbon.was_busy = uwsgi_calloc(sizeof(int) * uwsgi.numproc);
}
// set next update to now()+retry_delay, this way we will have first flush just after start
u_carbon.last_update = uwsgi_now() - u_carbon.freq + u_carbon.retry_delay;
uwsgi_log("[carbon] carbon plugin started, %is frequency, %is timeout, max retries %i, retry delay %is\n",
u_carbon.freq, u_carbon.timeout, u_carbon.max_retries, u_carbon.retry_delay);
struct uwsgi_stats_pusher_instance *uspi = uwsgi_stats_pusher_add(u_carbon.pusher, NULL);
uspi->freq = u_carbon.freq;
// no need to generate the json
uspi->raw=1;
}
int carbon_write(int *fd, char *fmt,...) {
static int carbon_write(int fd, char *fmt,...) {
va_list ap;
va_start(ap, fmt);
@@ -94,19 +128,21 @@ int carbon_write(int *fd, char *fmt,...) {
int rlen;
rlen = vsnprintf(ptr, 4096, fmt, ap);
va_end(ap);
if (rlen < 1) return 0;
if (write(*fd, ptr, rlen) <= 0) {
uwsgi_error("write()");
if (uwsgi_write_nb(fd, ptr, rlen, u_carbon.timeout)) {
uwsgi_error("carbon_write()");
return 0;
}
return 1;
}
void carbon_push_stats(int retry_cycle) {
static void carbon_push_stats(int retry_cycle, time_t now) {
struct carbon_server_list *usl = u_carbon.servers_data;
if (!u_carbon.servers_data) return;
int i;
int fd;
int wok;
@@ -114,6 +150,7 @@ void carbon_push_stats(int retry_cycle) {
for (i = 0; i < uwsgi.numproc; i++) {
u_carbon.current_busyness_values[i] = uwsgi.workers[i+1].running_time - u_carbon.last_busyness_values[i];
u_carbon.last_busyness_values[i] = uwsgi.workers[i+1].running_time;
u_carbon.was_busy[i-1] += uwsgi.workers[i+1].busy;
}
u_carbon.need_retry = 0;
@@ -137,7 +174,7 @@ void carbon_push_stats(int retry_cycle) {
u_carbon.need_retry = 1;
u_carbon.next_retry = uwsgi_now() + u_carbon.retry_delay;
} else {
uwsgi_log("[carbon] Maximum number of retries for %s (1)\n",
uwsgi_log("[carbon] Maximum number of retries for %s (%d)\n",
usl->value, u_carbon.max_retries);
usl->healthy = 0;
usl->errors = 0;
@@ -160,11 +197,13 @@ void carbon_push_stats(int retry_cycle) {
unsigned long long worker_busyness = 0;
unsigned long long total_harakiri = 0;
wok = carbon_write(&fd, "uwsgi.%s.%s.requests %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) uwsgi.workers[0].requests, (unsigned long long) uwsgi.current_time);
wok = carbon_write(fd, "%s%s.%s.requests %llu %llu\n", u_carbon.root_node, u_carbon.hostname, u_carbon.id, (unsigned long long) uwsgi.workers[0].requests, (unsigned long long) now);
if (!wok) goto clear;
for(i=1;i<=uwsgi.numproc;i++) {
total_tx += uwsgi.workers[i].tx;
total_harakiri += uwsgi.workers[i].harakiri_count;
if (uwsgi.workers[i].cheaped) {
// also if worker is cheaped than we report its average response time as zero, sending last value might be confusing
avg_rt = 0;
@@ -177,53 +216,63 @@ void carbon_push_stats(int retry_cycle) {
total_avg_rt += uwsgi.workers[i].avg_response_time;
// calculate worker busyness
worker_busyness = ((u_carbon.current_busyness_values[i-1]*100) / (u_carbon.freq*1000000));
if (worker_busyness > 100) worker_busyness = 100;
if (u_carbon.current_busyness_values[i-1] == 0 && u_carbon.was_busy[i-1]) {
worker_busyness = 100;
}
else {
worker_busyness = ((u_carbon.current_busyness_values[i-1]*100) / (u_carbon.freq*1000000));
if (worker_busyness > 100) worker_busyness = 100;
}
total_busyness += worker_busyness;
u_carbon.was_busy[i-1] = 0;
// only running workers are counted in total memory stats
total_rss += uwsgi.workers[i].rss_size;
total_vsz += uwsgi.workers[i].vsz_size;
total_harakiri += uwsgi.workers[i].harakiri_count;
if (uwsgi.shared->options[UWSGI_OPTION_MEMORY_DEBUG] == 1 || uwsgi.force_get_memusage) {
// only running workers are counted in total memory stats and if memory-report option is enabled
total_rss += uwsgi.workers[i].rss_size;
total_vsz += uwsgi.workers[i].vsz_size;
}
}
//skip per worker metrics when disabled
if (u_carbon.no_workers) continue;
wok = carbon_write(&fd, "uwsgi.%s.%s.worker%d.requests %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long) uwsgi.workers[i].requests, (unsigned long long) uwsgi.current_time);
wok = carbon_write(fd, "%s%s.%s.worker%d.requests %llu %llu\n", u_carbon.root_node, u_carbon.hostname, u_carbon.id, i, (unsigned long long) uwsgi.workers[i].requests, (unsigned long long) now);
if (!wok) goto clear;
wok = carbon_write(&fd, "uwsgi.%s.%s.worker%d.rss_size %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long) uwsgi.workers[i].rss_size, (unsigned long long) uwsgi.current_time);
if (uwsgi.shared->options[UWSGI_OPTION_MEMORY_DEBUG] == 1 || uwsgi.force_get_memusage) {
wok = carbon_write(fd, "%s%s.%s.worker%d.rss_size %llu %llu\n", u_carbon.root_node, u_carbon.hostname, u_carbon.id, i, (unsigned long long) uwsgi.workers[i].rss_size, (unsigned long long) now);
if (!wok) goto clear;
wok = carbon_write(fd, "%s%s.%s.worker%d.vsz_size %llu %llu\n", u_carbon.root_node, u_carbon.hostname, u_carbon.id, i, (unsigned long long) uwsgi.workers[i].vsz_size, (unsigned long long) now);
if (!wok) goto clear;
}
wok = carbon_write(fd, "%s%s.%s.worker%d.avg_rt %llu %llu\n", u_carbon.root_node, u_carbon.hostname, u_carbon.id, i, (unsigned long long) avg_rt, (unsigned long long) now);
if (!wok) goto clear;
wok = carbon_write(&fd, "uwsgi.%s.%s.worker%d.vsz_size %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long) uwsgi.workers[i].vsz_size, (unsigned long long) uwsgi.current_time);
wok = carbon_write(fd, "%s%s.%s.worker%d.tx %llu %llu\n", u_carbon.root_node, u_carbon.hostname, u_carbon.id, i, (unsigned long long) uwsgi.workers[i].tx, (unsigned long long) now);
if (!wok) goto clear;
wok = carbon_write(&fd, "uwsgi.%s.%s.worker%d.avg_rt %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long) avg_rt, (unsigned long long) uwsgi.current_time);
wok = carbon_write(fd, "%s%s.%s.worker%d.busyness %llu %llu\n", u_carbon.root_node, u_carbon.hostname, u_carbon.id, i, (unsigned long long) worker_busyness, (unsigned long long) now);
if (!wok) goto clear;
wok = carbon_write(&fd, "uwsgi.%s.%s.worker%d.tx %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long) uwsgi.workers[i].tx, (unsigned long long) uwsgi.current_time);
if (!wok) goto clear;
wok = carbon_write(&fd, "uwsgi.%s.%s.worker%d.busyness %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long) worker_busyness, (unsigned long long) uwsgi.current_time);
if (!wok) goto clear;
wok = carbon_write(&fd, "uwsgi.%s.%s.worker%d.harakiri %llu %llu\n", uwsgi.hostname, u_carbon.id, i, (unsigned long long) uwsgi.workers[i].harakiri_count, (unsigned long long) uwsgi.current_time);
wok = carbon_write(fd, "%s%s.%s.worker%d.harakiri %llu %llu\n", u_carbon.root_node, u_carbon.hostname, u_carbon.id, i, (unsigned long long) uwsgi.workers[i].harakiri_count, (unsigned long long) now);
if (!wok) goto clear;
}
wok = carbon_write(&fd, "uwsgi.%s.%s.rss_size %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) total_rss, (unsigned long long) uwsgi.current_time);
if (uwsgi.shared->options[UWSGI_OPTION_MEMORY_DEBUG] == 1 || uwsgi.force_get_memusage) {
wok = carbon_write(fd, "%s%s.%s.rss_size %llu %llu\n", u_carbon.root_node, u_carbon.hostname, u_carbon.id, (unsigned long long) total_rss, (unsigned long long) now);
if (!wok) goto clear;
wok = carbon_write(fd, "%s%s.%s.vsz_size %llu %llu\n", u_carbon.root_node, u_carbon.hostname, u_carbon.id, (unsigned long long) total_vsz, (unsigned long long) now);
if (!wok) goto clear;
}
wok = carbon_write(fd, "%s%s.%s.avg_rt %llu %llu\n", u_carbon.root_node, u_carbon.hostname, u_carbon.id, (unsigned long long) (active_workers ? total_avg_rt / active_workers : 0), (unsigned long long) now);
if (!wok) goto clear;
wok = carbon_write(&fd, "uwsgi.%s.%s.vsz_size %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) total_vsz, (unsigned long long) uwsgi.current_time);
if (!wok) goto clear;
wok = carbon_write(&fd, "uwsgi.%s.%s.avg_rt %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) (active_workers ? total_avg_rt / active_workers : 0), (unsigned long long) uwsgi.current_time);
if (!wok) goto clear;
wok = carbon_write(&fd, "uwsgi.%s.%s.tx %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) total_tx, (unsigned long long) uwsgi.current_time);
wok = carbon_write(fd, "%s%s.%s.tx %llu %llu\n", u_carbon.root_node, u_carbon.hostname, u_carbon.id, (unsigned long long) total_tx, (unsigned long long) now);
if (!wok) goto clear;
if (active_workers > 0) {
@@ -232,18 +281,18 @@ void carbon_push_stats(int retry_cycle) {
} else {
total_avg_busyness = 0;
}
wok = carbon_write(&fd, "uwsgi.%s.%s.busyness %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) total_avg_busyness, (unsigned long long) uwsgi.current_time);
wok = carbon_write(fd, "%s%s.%s.busyness %llu %llu\n", u_carbon.root_node, u_carbon.hostname, u_carbon.id, (unsigned long long) total_avg_busyness, (unsigned long long) now);
if (!wok) goto clear;
wok = carbon_write(&fd, "uwsgi.%s.%s.active_workers %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) active_workers, (unsigned long long) uwsgi.current_time);
wok = carbon_write(fd, "%s%s.%s.active_workers %llu %llu\n", u_carbon.root_node, u_carbon.hostname, u_carbon.id, (unsigned long long) active_workers, (unsigned long long) now);
if (!wok) goto clear;
if (uwsgi.cheaper) {
wok = carbon_write(&fd, "uwsgi.%s.%s.cheaped_workers %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) uwsgi.numproc - active_workers, (unsigned long long) uwsgi.current_time);
wok = carbon_write(fd, "%s%s.%s.cheaped_workers %llu %llu\n", u_carbon.root_node, u_carbon.hostname, u_carbon.id, (unsigned long long) uwsgi.numproc - active_workers, (unsigned long long) now);
if (!wok) goto clear;
}
wok = carbon_write(&fd, "uwsgi.%s.%s.harakiri %llu %llu\n", uwsgi.hostname, u_carbon.id, (unsigned long long) total_harakiri, (unsigned long long) uwsgi.current_time);
wok = carbon_write(fd, "%s%s.%s.harakiri %llu %llu\n", u_carbon.root_node, u_carbon.hostname, u_carbon.id, (unsigned long long) total_harakiri, (unsigned long long) now);
if (!wok) goto clear;
usl->healthy = 1;
@@ -260,28 +309,34 @@ nxt:
u_carbon.last_update -= u_carbon.timeout;
}
void carbon_master_cycle() {
static void carbon_push(struct uwsgi_stats_pusher_instance *uspi, time_t now, char *json, size_t json_len) {
if (!u_carbon.servers) return;
if (uwsgi.current_time - u_carbon.last_update >= u_carbon.freq || uwsgi.cleaning) {
if (u_carbon.need_retry && now >= u_carbon.next_retry) {
carbon_push_stats(1, now);
}
else {
// update
u_carbon.need_retry = 0;
carbon_push_stats(0);
} else if (u_carbon.need_retry && (uwsgi.current_time >= u_carbon.next_retry)) {
// retry failed servers
carbon_push_stats(1);
carbon_push_stats(0, now);
}
}
static void carbon_cleanup() {
carbon_push_stats(0, uwsgi_now());
}
static void carbon_register() {
u_carbon.pusher = uwsgi_register_stats_pusher("carbon", carbon_push);
}
struct uwsgi_plugin carbon_plugin = {
.name = "carbon",
.master_cleanup = carbon_master_cycle,
.master_cleanup = carbon_cleanup,
.options = carbon_options,
.master_cycle = carbon_master_cycle,
.on_load = carbon_register,
.post_init = carbon_post_init,
};
+1 -17
View File
@@ -834,23 +834,7 @@ void uwsgi_corerouter_loop(int id, void *data) {
}
// not having a hook could mean a previous event in the loop cleared it...
if (!hook) {
// a single event cannot be unexpected..
if (nevents == 1) {
if (interesting_fd == cr_session->instance_fd) {
uwsgi_log("[uwsgi-corerouter] BUG, unexpected event received from backend instance (fd: %d nevents: %d) !!!\n", interesting_fd, nevents);
}
else if (interesting_fd == cr_session->fd) {
uwsgi_log("[uwsgi-corerouter] BUG, unexpected event received from client (fd: %d nevents: %d)!!!\n", interesting_fd, nevents);
}
else {
uwsgi_log("[uwsgi-corerouter] BUG, unexpected event received !!!\n");
}
corerouter_close_session(ucr, cr_session);
}
continue;
}
if (!hook) continue;
// reset errno (as we use it for internal signalling)
errno = 0;
ssize_t ret = hook(cr_session);
+8
View File
@@ -59,6 +59,14 @@ void uwsgi_corerouter_setup_sockets(struct uwsgi_corerouter *ucr) {
uwsgi.no_defer_accept = current_defer_accept;
}
}
// fix SERVER_PORT
if (!ugs->port || !ugs->port_len) {
ugs->port = strchr(ugs->name, ':');
if (ugs->port) {
ugs->port++;
ugs->port_len = strlen(ugs->port);
}
}
// put socket in non-blocking mode
uwsgi_socket_nb(ugs->fd);
uwsgi_log("%s bound on %s fd %d\n", ucr->name, ugs->name, ugs->fd);
+4 -4
View File
@@ -230,7 +230,7 @@ ssize_t uwsgi_gevent_hook_input_read(struct wsgi_request *wsgi_req, char *tmp_bu
}
Py_DECREF(ret);
ret = PyObject_CallMethod(timer, "start", "OO", current, timer);
ret = PyObject_CallMethod(timer, "again", "OO", current, timer);
if (!ret) {
stop_the_watchers_and_clear
return -1;
@@ -298,7 +298,7 @@ ssize_t uwsgi_gevent_hook_input_readline(struct wsgi_request *wsgi_req, char *re
}
Py_DECREF(ret);
ret = PyObject_CallMethod(timer, "start", "OO", current, timer);
ret = PyObject_CallMethod(timer, "again", "OO", current, timer);
if (!ret) {
stop_the_watchers_and_clear
return -1;
@@ -364,7 +364,7 @@ void uwsgi_gevent_nb_write(struct wsgi_request *wsgi_req, PyObject *str) {
}
Py_DECREF(ret);
ret = PyObject_CallMethod(timer, "start", "OO", current, timer);
ret = PyObject_CallMethod(timer, "again", "OO", current, timer);
if (!ret) {
stop_the_watchers_and_clear
goto error;
@@ -431,7 +431,7 @@ PyObject *uwsgi_gevent_wait(PyObject *watcher, PyObject *timer, PyObject *curren
Py_DECREF(ret);
// start the timeout handler
ret = PyObject_CallMethod(timer, "start", "OO", current, timer);
ret = PyObject_CallMethod(timer, "again", "OO", current, timer);
if (!ret) return NULL;
Py_DECREF(ret);
+10 -8
View File
@@ -551,8 +551,8 @@ ssize_t hr_read_ssl_body(struct corerouter_session * cs) {
if (err == SSL_ERROR_WANT_READ) {
if (cs->event_hook_write) {
uwsgi_cr_hook_write(cs, NULL);
uwsgi_cr_hook_read(cs, hr_read_ssl_body);
}
uwsgi_cr_hook_read(cs, hr_read_ssl_body);
errno = EINPROGRESS;
return -1;
}
@@ -560,8 +560,8 @@ ssize_t hr_read_ssl_body(struct corerouter_session * cs) {
else if (err == SSL_ERROR_WANT_WRITE) {
if (cs->event_hook_read) {
uwsgi_cr_hook_read(cs, NULL);
uwsgi_cr_hook_write(cs, hr_read_ssl_body);
}
uwsgi_cr_hook_write(cs, hr_read_ssl_body);
errno = EINPROGRESS;
return -1;
}
@@ -625,16 +625,16 @@ ssize_t hr_write_ssl_response(struct corerouter_session * cs) {
if (err == SSL_ERROR_WANT_READ) {
if (cs->event_hook_write) {
uwsgi_cr_hook_write(cs, NULL);
uwsgi_cr_hook_read(cs, hr_write_ssl_response);
}
uwsgi_cr_hook_read(cs, hr_write_ssl_response);
errno = EINPROGRESS;
return -1;
}
else if (err == SSL_ERROR_WANT_WRITE) {
if (cs->event_hook_read) {
uwsgi_cr_hook_read(cs, NULL);
uwsgi_cr_hook_write(cs, hr_write_ssl_response);
}
uwsgi_cr_hook_write(cs, hr_write_ssl_response);
errno = EINPROGRESS;
return -1;
}
@@ -839,16 +839,16 @@ ssize_t hr_send_expect_continue(struct corerouter_session * cs) {
if (err == SSL_ERROR_WANT_READ) {
if (cs->event_hook_write) {
uwsgi_cr_hook_write(cs, NULL);
uwsgi_cr_hook_read(cs, hr_write_ssl_response);
}
uwsgi_cr_hook_read(cs, hr_write_ssl_response);
errno = EINPROGRESS;
return -1;
}
else if (err == SSL_ERROR_WANT_WRITE) {
if (cs->event_hook_read) {
uwsgi_cr_hook_read(cs, NULL);
uwsgi_cr_hook_write(cs, hr_write_ssl_response);
}
uwsgi_cr_hook_write(cs, hr_write_ssl_response);
errno = EINPROGRESS;
return -1;
}
@@ -949,8 +949,8 @@ ssize_t hr_recv_http_ssl(struct corerouter_session * cs) {
if (err == SSL_ERROR_WANT_READ) {
if (cs->event_hook_write) {
uwsgi_cr_hook_write(cs, NULL);
uwsgi_cr_hook_read(cs, hr_recv_http_ssl);
}
uwsgi_cr_hook_read(cs, hr_recv_http_ssl);
errno = EINPROGRESS;
return -1;
}
@@ -958,8 +958,8 @@ ssize_t hr_recv_http_ssl(struct corerouter_session * cs) {
else if (err == SSL_ERROR_WANT_WRITE) {
if (cs->event_hook_read) {
uwsgi_cr_hook_read(cs, NULL);
uwsgi_cr_hook_write(cs, hr_recv_http_ssl);
}
uwsgi_cr_hook_write(cs, hr_recv_http_ssl);
errno = EINPROGRESS;
return -1;
}
@@ -1125,6 +1125,8 @@ void hr_session_ssl_close(struct corerouter_session *cs) {
X509_free(hs->ssl_client_cert);
}
// clear the errors (otherwise they could be propagated)
ERR_clear_error();
SSL_free(hs->ssl);
}
#endif
-34
View File
@@ -1,34 +0,0 @@
#include "../../uwsgi.h"
#include <jni.h>
struct uwsgi_jvm {
struct uwsgi_string_list *classpath;
JNIEnv *env;
char *class;
jclass main_class;
jclass str_class;
jclass ht_class;
jclass fd_class;
};
jmethodID uwsgi_jvm_get_method_id(jclass, char *, char *);
jmethodID uwsgi_jvm_get_static_method_id(jclass, char *, char *);
jclass uwsgi_jvm_get_class(char *);
jclass uwsgi_jvm_get_object_class(jobject);
int uwsgi_jvm_exception(void);
jobject uwsgi_jvm_str_new(char *, int );
jobject uwsgi_jvm_str(char *);
jobject uwsgi_jvm_array_get(jobject , int );
jobject uwsgi_jvm_ht_new(void);
jobject uwsgi_jvm_ht_put(jobject, jobject, jobject);
jobject uwsgi_jvm_fd(int);
char *uwsgi_jvm_str2c(jobject);
int uwsgi_jvm_strlen2c(jobject);
-210
View File
@@ -1,210 +0,0 @@
#include "jvm.h"
/*
with javap -s -p <class>
you can get method signatures
This plugin is the core for all of the JVM-based ones
*/
struct uwsgi_jvm ujvm;
struct uwsgi_option uwsgi_jvm_options[] = {
{"jvm-main-class", required_argument, 0, "load the specified class", uwsgi_opt_set_str, &ujvm.class, 0},
{"jvm-classpath", required_argument, 0, "add the specified directory to the classpath", uwsgi_opt_add_string_list, &ujvm.classpath, 0},
{0, 0, 0, 0},
};
int uwsgi_jvm_exception(void) {
if ((*ujvm.env)->ExceptionOccurred(ujvm.env)) {
(*ujvm.env)->ExceptionDescribe(ujvm.env);
(*ujvm.env)->ExceptionClear(ujvm.env);
return 1;
}
return 0;
}
jclass uwsgi_jvm_get_object_class(jobject obj) {
return (*ujvm.env)->GetObjectClass(ujvm.env, obj);
}
jclass uwsgi_jvm_get_class(char *name) {
jclass my_class = (*ujvm.env)->FindClass(ujvm.env, name);
if (uwsgi_jvm_exception()) {
return NULL;
}
return my_class;
}
jmethodID uwsgi_jvm_get_method_id(jclass cls, char *name, char *signature) {
jmethodID mid;
mid = (*ujvm.env)->GetMethodID(ujvm.env, cls, name, signature);
return mid;
}
jmethodID uwsgi_jvm_get_static_method_id(jclass cls, char *name, char *signature) {
jmethodID mid;
mid = (*ujvm.env)->GetStaticMethodID(ujvm.env, cls, name, signature);
return mid;
}
jobject uwsgi_jvm_str_new(char *str, int len) {
jbyteArray ba;
static jmethodID str_new_mid = 0;
if (!str_new_mid) {
str_new_mid = uwsgi_jvm_get_method_id(ujvm.str_class, "<init>", "([BLjava/lang/String;)V");
}
ba = (*ujvm.env)->NewByteArray(ujvm.env, len);
(*ujvm.env)->SetByteArrayRegion(ujvm.env, ba, 0, len, (jbyte *) str);
return (*ujvm.env)->NewObject(ujvm.env, ujvm.str_class, str_new_mid, ba,
(*ujvm.env)->NewStringUTF(ujvm.env, "UTF-8"));
}
jobject uwsgi_jvm_str(char *str) {
return (*ujvm.env)->NewStringUTF(ujvm.env, str);
}
int jvm_init(void) {
jint res;
JavaVM *jvm;
JavaVMInitArgs vm_args;
JavaVMOption options[1];
jmethodID mmid;
char *old_cp = NULL ;
vm_args.version = JNI_VERSION_1_2;
JNI_GetDefaultJavaVMInitArgs(&vm_args);
options[0].optionString = "-Djava.class.path=.";
struct uwsgi_string_list *cp = ujvm.classpath;
while(cp) {
if (old_cp) {
options[0].optionString = uwsgi_concat3(old_cp, ":", cp->value);
free(old_cp);
}
else {
options[0].optionString = uwsgi_concat3(options[0].optionString, ":", cp->value);
}
old_cp = options[0].optionString ;
cp = cp->next;
}
vm_args.options = options;
vm_args.nOptions = 1;
res = JNI_CreateJavaVM(&jvm, (void **) &ujvm.env, &vm_args);
if (res) {
uwsgi_log("unable to initialize JVM\n");
exit(1);
}
uwsgi_log("JVM initialized\n");
if (ujvm.class) {
ujvm.main_class = uwsgi_jvm_get_class(ujvm.class);
if (!ujvm.main_class) {
exit(1);
}
mmid = uwsgi_jvm_get_static_method_id(ujvm.main_class, "main", "([Ljava/lang/String;)V");
if (mmid) {
(*ujvm.env)->CallStaticVoidMethod(ujvm.env, ujvm.main_class, mmid);
uwsgi_jvm_exception();
}
}
ujvm.str_class = uwsgi_jvm_get_class("java/lang/String");
ujvm.ht_class = uwsgi_jvm_get_class("java/util/Hashtable");
ujvm.fd_class = uwsgi_jvm_get_class("java/io/FileDescriptor");
return 1;
}
jobject uwsgi_jvm_array_get(jobject obj, int index) {
return (*ujvm.env)->GetObjectArrayElement(ujvm.env, obj, index);
}
jobject uwsgi_jvm_ht_new() {
static jmethodID htimid = 0;
if (!htimid) {
htimid = uwsgi_jvm_get_method_id(ujvm.ht_class, "<init>", "()V");
}
return (*ujvm.env)->NewObject(ujvm.env, ujvm.ht_class, htimid);
}
jobject uwsgi_jvm_ht_put(jobject obj, jobject key, jobject val) {
static jmethodID htpmid = 0 ;
if (!htpmid) {
htpmid = uwsgi_jvm_get_method_id(ujvm.ht_class, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
}
return (*ujvm.env)->CallObjectMethod(ujvm.env, obj, htpmid, key, val);
}
jobject uwsgi_jvm_fd(int fd) {
jobject fd_obj;
static jmethodID fd_mid = 0;
static jfieldID fd_field = 0 ;
if (!fd_mid) {
fd_mid = uwsgi_jvm_get_method_id( ujvm.fd_class, "<init>", "()V");
}
fd_obj = (*ujvm.env)->NewObject(ujvm.env, ujvm.fd_class, fd_mid);
if (!fd_field) {
fd_field = (*ujvm.env)->GetFieldID(ujvm.env, ujvm.fd_class, "fd", "I");
}
(*ujvm.env)->SetIntField(ujvm.env, fd_obj, fd_field, fd);
return fd_obj;
}
char *uwsgi_jvm_str2c(jobject obj) {
return (char *) (*ujvm.env)->GetStringUTFChars(ujvm.env, obj, NULL);
}
int uwsgi_jvm_strlen2c(jobject obj) {
return (*ujvm.env)->GetStringUTFLength(ujvm.env, obj);
}
struct uwsgi_plugin jvm_plugin = {
.name = "jvm",
.init = jvm_init,
.options = uwsgi_jvm_options,
};
-47
View File
@@ -1,47 +0,0 @@
import os,sys
NAME='jvm'
# Snow Leopard
#JVM_INCPATH = "/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Headers/"
#JVM_LIBPATH = "/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Libraries/ -framework JavaVM"
# FreeBSD openjdk7 example
# env UWSGICONFIG_JVM_INCPATH="/usr/local/openjdk7/include -I/usr/local/openjdk7/include/freebsd/" UWSGICONFIG_JVM_LIBPATH="/usr/local/openjdk7/jre/lib/amd64/server" python uwsgiconfig.py --plugin plugins/jvm
# NexentaOS example
# UWSGICONFIG_JVM_INCPATH="/usr/java/include -I /usr/java/include/solaris" UWSGICONFIG_JVM_LIBPATH="/usr/java/jre/lib/i386/" python uwsgiconfig.py --plugin plugins/jvm
# Ubuntu
JVM_INCPATH = "/usr/lib/jvm/java-6-openjdk/include/ -I/usr/lib/jvm/java-6-openjdk/include/linux"
JVM_LIBPATH = "/usr/lib/jvm/java-6-openjdk/jre/lib/amd64/server/"
try:
JVM_INCPATH = os.environ['UWSGICONFIG_JVM_INCPATH']
except:
pass
try:
JVM_LIBPATH = os.environ['UWSGICONFIG_JVM_LIBPATH']
except:
pass
try:
JVM_INCPATH = os.environ['UWSGICONFIG_JVM_INCPATH']
except:
pass
try:
JVM_LIBPATH = os.environ['UWSGICONFIG_JVM_LIBPATH']
except:
pass
CFLAGS = ['-I' + JVM_INCPATH]
LDFLAGS = ['-L' + JVM_LIBPATH]
LIBS = ['-ljvm']
GCC_LIST = ['jvm_plugin']
if os.environ.has_key('LD_RUN_PATH'):
os.environ['LD_RUN_PATH'] += ':' + JVM_LIBPATH
else:
os.environ['LD_RUN_PATH'] = JVM_LIBPATH
-117
View File
@@ -1,117 +0,0 @@
#include "../jvm/jvm.h"
extern struct uwsgi_server uwsgi;
extern struct uwsgi_jvm ujvm;
void uwsgi_jwsgi_init(void) {
}
int uwsgi_jwsgi_request(struct wsgi_request *wsgi_req) {
jmethodID jmid;
int i;
jobject env;
jobject hkey, hval;
jobject response;
jobject status;
jobject headers, header;
jobject body;
jclass hc;
jmethodID hh_size, hh_get;
int hlen;
if (!wsgi_req->uh.pktsize) {
uwsgi_log("Invalid JWSGI request. skip.\n");
return -1;
}
if (uwsgi_parse_vars(wsgi_req)) {
uwsgi_log("Invalid JWSGI request. skip.\n");
return -1;
}
jmid = uwsgi_jvm_get_static_method_id(ujvm.main_class, "jwsgi", "(Ljava/util/Hashtable;)[Ljava/lang/Object;");
uwsgi_log("jwsgi method id = %d\n", jmid);
env = uwsgi_jvm_ht_new();
uwsgi_jvm_exception();
for(i=0;i<wsgi_req->var_cnt;i++) {
uwsgi_jvm_ht_put(env,
uwsgi_jvm_str_new(wsgi_req->hvec[i].iov_base, wsgi_req->hvec[i].iov_len),
uwsgi_jvm_str_new(wsgi_req->hvec[i+1].iov_base, wsgi_req->hvec[i+1].iov_len)
);
// check if something is going wrong during hashtable fill
uwsgi_jvm_exception();
i++;
}
uwsgi_log("env created\n");
uwsgi_jvm_ht_put(env, uwsgi_jvm_str("jwsgi.input"), uwsgi_jvm_fd(wsgi_req->poll.fd));
uwsgi_log("jwsgi.input created\n");
response = (*ujvm.env)->CallObjectMethod(ujvm.env, ujvm.main_class, jmid, env);
uwsgi_jvm_exception();
uwsgi_log("RESPONSE SIZE %d\n", (*ujvm.env)->GetArrayLength(ujvm.env, response));
status = uwsgi_jvm_array_get(response, 0);
uwsgi_jvm_exception();
wsgi_req->headers_size += write(wsgi_req->poll.fd, wsgi_req->protocol, wsgi_req->protocol_len);
wsgi_req->headers_size += write(wsgi_req->poll.fd, " ", 1);
wsgi_req->headers_size += write(wsgi_req->poll.fd, uwsgi_jvm_str2c(status), uwsgi_jvm_strlen2c(status));
wsgi_req->headers_size += write(wsgi_req->poll.fd, "\r\n", 2);
headers = uwsgi_jvm_array_get(response, 1);
hc = uwsgi_jvm_get_object_class(headers);
hh_size = uwsgi_jvm_get_method_id(hc, "size","()I");
hh_get = uwsgi_jvm_get_method_id(hc, "get","(I)Ljava/lang/Object;");
hlen = (*ujvm.env)->CallIntMethod(ujvm.env, headers, hh_size);
for(i=0;i<hlen;i++) {
header = (*ujvm.env)->CallObjectMethod(ujvm.env, headers, hh_get, i);
hkey = uwsgi_jvm_array_get(header, 0);
hval = uwsgi_jvm_array_get(header, 1);
wsgi_req->headers_size += write(wsgi_req->poll.fd, uwsgi_jvm_str2c(hkey), uwsgi_jvm_strlen2c(hkey));
wsgi_req->headers_size += write(wsgi_req->poll.fd, ": ", 2);
wsgi_req->headers_size += write(wsgi_req->poll.fd, uwsgi_jvm_str2c(hval), uwsgi_jvm_strlen2c(hval));
wsgi_req->headers_size += write(wsgi_req->poll.fd, "\r\n", 2);
}
wsgi_req->headers_size += write(wsgi_req->poll.fd, "\r\n", 2);
body = uwsgi_jvm_array_get(response, 2);
wsgi_req->response_size = write(wsgi_req->poll.fd, (*ujvm.env)->GetStringUTFChars(ujvm.env, body, NULL), (*ujvm.env)->GetStringUTFLength(ujvm.env, body));
return 1;
}
void uwsgi_jwsgi_after_request(struct wsgi_request *wsgi_req) {
log_request(wsgi_req);
}
struct uwsgi_plugin jwsgi_plugin = {
.name = "jwsgi",
.modifier1 = 8,
.request = uwsgi_jwsgi_request,
.after_request = uwsgi_jwsgi_after_request,
};
-22
View File
@@ -1,22 +0,0 @@
import os,sys
NAME='jwsgi'
# Snow Leopard
#JVM_INCPATH = "/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Headers/"
#JVM_LIBPATH = "/Developer/SDKs/MacOSX10.6.sdk/System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Libraries/ -framework JavaVM"
# Ubuntu
JVM_INCPATH = "/usr/lib/jvm/java-6-sun-1.6.0.15/include/ -I/usr/lib/jvm/java-6-sun-1.6.0.15/include/linux"
JVM_LIBPATH = "/usr/lib/jvm/java-6-sun-1.6.0.15/jre/lib/i386/server/"
CFLAGS = ['-I' + JVM_INCPATH]
LDFLAGS = ['-L' + JVM_LIBPATH]
LIBS = ['-ljvm']
GCC_LIST = ['jwsgi_plugin']
if os.environ.has_key('LD_RUN_PATH'):
os.environ['LD_RUN_PATH'] += ':' + JVM_LIBPATH
else:
os.environ['LD_RUN_PATH'] = JVM_LIBPATH
+60 -17
View File
@@ -133,30 +133,70 @@ static char *encode_lua_table(lua_State *L, int index, uint16_t *size) {
static int uwsgi_api_cache_set(lua_State *L) {
int args = lua_gettop(L);
int args = lua_gettop(L);
const char *key ;
const char *value ;
uint64_t expires = 0;
size_t vallen;
size_t vallen;
if (!uwsgi.cache_max_items) goto error;
if (args > 1) {
if (args > 1) {
key = lua_tolstring(L, 1, NULL);
value = lua_tolstring(L, 2, &vallen);
if (args > 2) {
expires = lua_tonumber(L, 3);
}
key = lua_tolstring(L, 1, NULL);
value = lua_tolstring(L, 2, &vallen);
if (args > 2) {
expires = lua_tonumber(L, 3);
}
uwsgi_cache_set((char *)key, strlen(key), (char *)value, (uint16_t) vallen, expires, 0);
}
uwsgi_wlock(uwsgi.cache_lock);
uwsgi_cache_set((char *)key, strlen(key), (char *)value, (uint16_t) vallen, expires, 0);
uwsgi_rwunlock(uwsgi.cache_lock);
}
lua_pushnil(L);
return 1;
error:
lua_pushnil(L);
return 1;
}
static int uwsgi_api_cache_update(lua_State *L) {
int args = lua_gettop(L);
const char *key ;
const char *value ;
uint64_t expires = 0;
size_t vallen;
if (!uwsgi.cache_max_items) goto error;
if (args > 1) {
key = lua_tolstring(L, 1, NULL);
value = lua_tolstring(L, 2, &vallen);
if (args > 2) {
expires = lua_tonumber(L, 3);
}
uwsgi_wlock(uwsgi.cache_lock);
uwsgi_cache_set((char *)key, strlen(key), (char *)value,
(uint16_t) vallen, expires,
UWSGI_CACHE_FLAG_UPDATE);
uwsgi_rwunlock(uwsgi.cache_lock);
}
error:
lua_pushnil(L);
return 1;
}
static int uwsgi_api_register_signal(lua_State *L) {
int args = lua_gettop(L);
@@ -184,23 +224,25 @@ static int uwsgi_api_cache_get(lua_State *L) {
char *value ;
uint64_t valsize;
const char *key ;
lca(L, 1);
if (!uwsgi.cache_max_items) goto error;
if (lua_isstring(L, 1)) {
key = lua_tolstring(L, 1, NULL);
uwsgi_rlock(uwsgi.cache_lock);
value = uwsgi_cache_get((char *)key, strlen(key), &valsize);
if (value) {
lua_pushlstring(L, value, valsize);
uwsgi_rwunlock(uwsgi.cache_lock);
return 1;
}
uwsgi_rwunlock(uwsgi.cache_lock);
}
error:
lua_pushnil(L);
return 1;
}
@@ -349,6 +391,7 @@ static const luaL_reg uwsgi_api[] = {
{"send_message", uwsgi_api_send_message},
{"cache_get", uwsgi_api_cache_get},
{"cache_set", uwsgi_api_cache_set},
{"cache_update", uwsgi_api_cache_update},
{"register_signal", uwsgi_api_register_signal},
{"register_rpc", uwsgi_api_register_rpc},
{"lock", uwsgi_api_lock},
-35
View File
@@ -1,35 +0,0 @@
#include "../../uwsgi.h"
struct uwsgi_mono {
char *assembly_name ;
} um;
int uwsgi_mono_init() {
MonoDomain *domain;
MonoAssembly *assembly;
MonoImage *image, *corlib;
domain = mono_jit_init("uwsgi");
corlib = mono_get_corlib();
if (!corlib) {
uwsgi_log("unable to initialize MONO engine\n");
exit(1);
}
image = mono_assembly_get_image(assembly);
}
struct uwsgi_plugin mono_plugin = {
.name = "mono",
.init = uwsgi_mono_init,
};
+3
View File
@@ -23,6 +23,9 @@ struct uwsgi_perl {
int no_die_catch;
int stacktrace_available;
char *argv_items;
struct uwsgi_string_list *argv_item;
// this is a pointer to the main list of interpreters (required for signals, rpc....);
PerlInterpreter **main;
+35 -3
View File
@@ -21,7 +21,12 @@ XS(XS_error) {
psgi_check_args(0);
ST(0) = sv_bless(newRV(sv_newmortal()), ((HV **)wi->error)[wsgi_req->async_id]);
if (uwsgi.threads > 1) {
ST(0) = sv_bless(newRV(sv_newmortal()), ((HV **)wi->error)[wsgi_req->async_id]);
}
else {
ST(0) = sv_bless(newRV(sv_newmortal()), ((HV **)wi->error)[0]);
}
XSRETURN(1);
}
@@ -32,7 +37,12 @@ XS(XS_input) {
struct uwsgi_app *wi = &uwsgi_apps[wsgi_req->app_id];
psgi_check_args(0);
ST(0) = sv_bless(newRV(sv_newmortal()), ((HV **)wi->input)[wsgi_req->async_id]);
if (uwsgi.threads > 1) {
ST(0) = sv_bless(newRV(sv_newmortal()), ((HV **)wi->input)[wsgi_req->async_id]);
}
else {
ST(0) = sv_bless(newRV(sv_newmortal()), ((HV **)wi->input)[0]);
}
XSRETURN(1);
}
@@ -66,7 +76,12 @@ XS(XS_stream)
while (psgi_response(wsgi_req, response) != UWSGI_OK);
SvREFCNT_dec(response);
ST(0) = sv_bless(newRV(sv_newmortal()), ((HV **)wi->stream)[wsgi_req->async_id]);
if (uwsgi.threads > 1) {
ST(0) = sv_bless(newRV(sv_newmortal()), ((HV **)wi->stream)[wsgi_req->async_id]);
}
else {
ST(0) = sv_bless(newRV(sv_newmortal()), ((HV **)wi->stream)[0]);
}
XSRETURN(1);
}
else {
@@ -413,6 +428,23 @@ int init_psgi_app(struct wsgi_request *wsgi_req, char *app, uint16_t app_len, Pe
}
}
if (uperl.argv_items || uperl.argv_item) {
AV *uperl_argv = GvAV(PL_argvgv);
if (uperl.argv_items) {
char *argv_list = uwsgi_str(uperl.argv_items);
char *p = strtok(argv_list, " ");
while(p) {
av_push(uperl_argv, newSVpv(p, 0));
p = strtok(NULL, " ");
}
}
struct uwsgi_string_list *usl = uperl.argv_item;
while(usl) {
av_push(uperl_argv, newSVpv(usl->value, usl->len));
usl = usl->next;
}
}
SV *dollar_zero = get_sv("0", GV_ADD);
sv_setsv(dollar_zero, newSVpv(app, app_len));
+38 -7
View File
@@ -19,6 +19,8 @@ struct uwsgi_option uwsgi_perl_options[] = {
#ifdef PERL_VERSION_STRING
{"perl-version", no_argument, 0, "print perl version", uwsgi_opt_print, PERL_VERSION_STRING, UWSGI_OPT_IMMEDIATE},
#endif
{"perl-args", required_argument, 0, "add items (space separated) to @ARGV", uwsgi_opt_set_str, &uperl.argv_items, 0},
{"perl-arg", required_argument, 0, "add an item to @ARGV", uwsgi_opt_add_string_list, &uperl.argv_item, 0},
{0, 0, 0, 0, 0, 0, 0},
};
@@ -60,7 +62,12 @@ SV *uwsgi_perl_call_stream(SV *func) {
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs( sv_2mortal(newRV((SV*) ((SV **)wi->responder0)[wsgi_req->async_id])));
if (uwsgi.threads > 1) {
XPUSHs( sv_2mortal(newRV((SV*) ((SV **)wi->responder0)[wsgi_req->async_id])));
}
else {
XPUSHs( sv_2mortal(newRV((SV*) ((SV **)wi->responder0)[0])));
}
PUTBACK;
call_sv( func, G_SCALAR | G_EVAL);
@@ -294,7 +301,12 @@ SV *build_psgi_env(struct wsgi_request *wsgi_req) {
if (!hv_store(env, "psgix.input.buffered", 20, newSViv(wsgi_req->body_as_file), 0)) goto clear;
if (!hv_store(env, "psgix.logger", 12,newRV((SV*) ((SV **)wi->responder1)[wsgi_req->async_id]) ,0)) goto clear;
if (uwsgi.threads > 1) {
if (!hv_store(env, "psgix.logger", 12,newRV((SV*) ((SV **)wi->responder1)[wsgi_req->async_id]) ,0)) goto clear;
}
else {
if (!hv_store(env, "psgix.logger", 12,newRV((SV*) ((SV **)wi->responder1)[0]) ,0)) goto clear;
}
if (uwsgi.master_process) {
if (!hv_store(env, "psgix.harakiri", 14, newSViv(1), 0)) goto clear;
@@ -429,8 +441,15 @@ int uwsgi_perl_request(struct wsgi_request *wsgi_req) {
struct uwsgi_app *wi = &uwsgi_apps[wsgi_req->app_id];
wi->requests++;
if (((PerlInterpreter **)wi->interpreter)[wsgi_req->async_id] != uperl.main[wsgi_req->async_id]) {
PERL_SET_CONTEXT(((PerlInterpreter **)wi->interpreter)[wsgi_req->async_id]);
if (uwsgi.threads < 2) {
if (((PerlInterpreter **)wi->interpreter)[0] != uperl.main[0]) {
PERL_SET_CONTEXT(((PerlInterpreter **)wi->interpreter)[0]);
}
}
else {
if (((PerlInterpreter **)wi->interpreter)[wsgi_req->async_id] != uperl.main[wsgi_req->async_id]) {
PERL_SET_CONTEXT(((PerlInterpreter **)wi->interpreter)[wsgi_req->async_id]);
}
}
ENTER;
@@ -439,7 +458,12 @@ int uwsgi_perl_request(struct wsgi_request *wsgi_req) {
wsgi_req->async_environ = build_psgi_env(wsgi_req);
if (!wsgi_req->async_environ) goto clear;
wsgi_req->async_result = psgi_call(wsgi_req, ((SV **)wi->callable)[wsgi_req->async_id], wsgi_req->async_environ);
if (uwsgi.threads > 1) {
wsgi_req->async_result = psgi_call(wsgi_req, ((SV **)wi->callable)[wsgi_req->async_id], wsgi_req->async_environ);
}
else {
wsgi_req->async_result = psgi_call(wsgi_req, ((SV **)wi->callable)[0], wsgi_req->async_environ);
}
if (!wsgi_req->async_result) goto clear;
if (SvTYPE((AV *)wsgi_req->async_result) == SVt_PVCV) {
@@ -472,8 +496,15 @@ clear:
LEAVE;
// restore main interpreter if needed
if (((PerlInterpreter **)wi->interpreter)[wsgi_req->async_id] != uperl.main[wsgi_req->async_id]) {
PERL_SET_CONTEXT(uperl.main[wsgi_req->async_id]);
if (uwsgi.threads > 1) {
if (((PerlInterpreter **)wi->interpreter)[wsgi_req->async_id] != uperl.main[wsgi_req->async_id]) {
PERL_SET_CONTEXT(uperl.main[wsgi_req->async_id]);
}
}
else {
if (((PerlInterpreter **)wi->interpreter)[0] != uperl.main[0]) {
PERL_SET_CONTEXT(uperl.main[0]);
}
}
return UWSGI_OK;
-1
View File
@@ -46,7 +46,6 @@ int psgi_response(struct wsgi_request *wsgi_req, AV *response) {
if (SvTRUE(*harakiri)) wsgi_req->async_plagued = 1;
}
SvREFCNT_dec(wsgi_req->async_environ);
SvREFCNT_dec(wsgi_req->async_result);
return UWSGI_OK;
+37
View File
@@ -290,6 +290,41 @@ XS(XS_signal_wait) {
XSRETURN_YES;
}
XS(XS_add_timer) {
dXSARGS;
psgi_check_args(2);
uint8_t uwsgi_signal = SvIV(ST(0));
int seconds = SvIV(ST(1));
if (uwsgi_add_timer(uwsgi_signal, seconds)) {
croak("unable to register timer");
XSRETURN_UNDEF;
}
XSRETURN(1);
}
XS(XS_add_rb_timer) {
dXSARGS;
psgi_check_args(2);
uint8_t uwsgi_signal = SvIV(ST(0));
int seconds = SvIV(ST(1));
if (uwsgi_signal_add_rb_timer(uwsgi_signal, seconds, 0)) {
croak("unable to register rb timer");
XSRETURN_UNDEF;
}
XSRETURN(1);
}
void init_perl_embedded_module() {
psgi_xs(reload);
@@ -307,5 +342,7 @@ void init_perl_embedded_module() {
psgi_xs(signal_wait);
psgi_xs(postfork);
psgi_xs(atexit);
psgi_xs(add_timer);
psgi_xs(add_rb_timer);
}
+3 -2
View File
@@ -211,8 +211,9 @@ void init_pyargv() {
#endif
if (*ap != '\0') {
#ifdef PYTHREE
mbstowcs( wcargv + strlen(ap), ap, strlen(ap));
up.py_argv[up.argc] = wcargv + strlen(ap);
mbstowcs( wcargv, ap, strlen(ap));
up.py_argv[up.argc] = wcargv;
wcargv += strlen(ap) + 1;
#else
up.py_argv[up.argc] = ap;
#endif
+1 -1
View File
@@ -842,7 +842,7 @@ PyObject *py_uwsgi_advanced_sendfile(PyObject * self, PyObject * args) {
}
#ifdef PYTHREE
else if (PyUnicode_Check(what)) {
filename = PyBytes_AsString(PyUnicode_AsASCIIString(what));
filename = PyBytes_AsString(PyUnicode_AsLatin1String(what));
fd = open(filename, O_RDONLY);
if (fd < 0) {
+28 -13
View File
@@ -2,9 +2,16 @@ import os,sys
from distutils import sysconfig
def get_python_version():
version = sysconfig.get_config_var('VERSION')
try:
version = version + sys.abiflags
except:
pass
return version
NAME='python'
GCC_LIST = ['python_plugin', 'pyutils', 'pyloader', 'wsgi_handlers', 'wsgi_headers', 'wsgi_subhandler', 'web3_subhandler', 'pump_subhandler', 'gil', 'uwsgi_pymodule', 'profiler', 'symimporter', 'tracebacker']
#OBJ_LIST = ['/usr/lib/libpython2.6.a']
CFLAGS = ['-I' + sysconfig.get_python_inc(), '-I' + sysconfig.get_python_inc(plat_specific=True) ]
@@ -15,8 +22,26 @@ LDFLAGS = []
if not 'UWSGI_PYTHON_NOLIB' in os.environ:
LIBS = sysconfig.get_config_var('LIBS').split() + sysconfig.get_config_var('SYSLIBS').split()
# check if it is a non-shared build (but please, add --enable-shared to your python's ./configure script)
if not sysconfig.get_config_var('Py_ENABLE_SHARED'):
LIBS.append('-L' + sysconfig.get_config_var('LIBPL'))
libdir = sysconfig.get_config_var('LIBPL')
# libdir does not exists, try to get it from the venv
version = get_python_version()
if not os.path.exists(libdir):
libdir = '%s/lib/python%s/config' % (sys.prefix, version)
# try skipping abiflag
if not os.path.exists(libdir) and version.endswith('m'):
version = version[:-1]
libdir = '%s/lib/python%s/config' % (sys.prefix, version)
# try 3.x style config dir
if not os.path.exists(libdir):
libdir = '%s/lib/python%s/config-%s' % (sys.prefix, version, get_python_version())
libpath = '%s/%s' % (libdir, sysconfig.get_config_var('LDLIBRARY'))
if not os.path.exists(libpath):
libpath = '%s/%s' % (libdir, sysconfig.get_config_var('LIBRARY'))
if not os.path.exists(libpath):
libpath = '%s/libpython%s.a' % (libdir, version)
LIBS.append(libpath)
else:
try:
LDFLAGS.append("-L%s" % sysconfig.get_config_var('LIBDIR'))
@@ -25,16 +50,6 @@ if not 'UWSGI_PYTHON_NOLIB' in os.environ:
LDFLAGS.append("-L%s/lib" % sysconfig.PREFIX)
os.environ['LD_RUN_PATH'] = "%s/lib" % sysconfig.PREFIX
version = sysconfig.get_config_var('VERSION')
try:
version = version + sys.abiflags
except:
pass
LIBS.append('-lpython' + version)
LIBS.append('-lpython%s' % get_python_version())
else:
LIBS = []
#if str(PYLIB_PATH) != '':
# libs.insert(0,'-L' + PYLIB_PATH)
# os.environ['LD_RUN_PATH'] = PYLIB_PATH
+3
View File
@@ -588,6 +588,9 @@ PyObject *py_uwsgi_sendfile(PyObject * self, PyObject * args) {
#ifdef PYTHREE
wsgi_req->sendfile_fd = PyObject_AsFileDescriptor(wsgi_req->async_sendfile);
if (wsgi_req->sendfile_fd >= 0) {
Py_INCREF((PyObject *)wsgi_req->async_sendfile);
}
#else
if (PyFile_Check((PyObject *)wsgi_req->async_sendfile)) {
Py_INCREF((PyObject *)wsgi_req->async_sendfile);
+4 -4
View File
@@ -100,7 +100,7 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) {
wsgi_req->hvec[1].iov_len = 1;
#ifdef PYTHREE
if (self != Py_None) {
PyObject *zero = PyUnicode_AsASCIIString(head);
PyObject *zero = PyUnicode_AsLatin1String(head);
wsgi_req->hvec[2].iov_base = PyBytes_AsString(zero);
PyList_Append((PyObject *) wsgi_req->gc_tracker, zero);
Py_DECREF(zero);
@@ -124,7 +124,7 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) {
wsgi_req->hvec[0].iov_len = 8;
#ifdef PYTHREE
if (self != Py_None) {
PyObject *zero = PyUnicode_AsASCIIString(head);
PyObject *zero = PyUnicode_AsLatin1String(head);
wsgi_req->hvec[1].iov_base = PyBytes_AsString(zero);
PyList_Append((PyObject *) wsgi_req->gc_tracker, zero);
Py_DECREF(zero);
@@ -198,7 +198,7 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) {
#ifdef PYTHREE
if (self != Py_None) {
PyObject *zero = PyUnicode_AsASCIIString(h_key);
PyObject *zero = PyUnicode_AsLatin1String(h_key);
wsgi_req->hvec[j].iov_base = PyBytes_AsString(zero);
PyList_Append((PyObject *) wsgi_req->gc_tracker, zero);
Py_DECREF(zero);
@@ -215,7 +215,7 @@ PyObject *py_uwsgi_spit(PyObject * self, PyObject * args) {
wsgi_req->hvec[j + 1].iov_len = H_SEP_SIZE;
#ifdef PYTHREE
if (self != Py_None) {
PyObject *zero = PyUnicode_AsASCIIString(h_value);
PyObject *zero = PyUnicode_AsLatin1String(h_value);
wsgi_req->hvec[j + 2].iov_base = PyBytes_AsString(zero);
PyList_Append((PyObject *) wsgi_req->gc_tracker, zero);
Py_DECREF(zero);
+2
View File
@@ -254,8 +254,10 @@ VALUE rb_uwsgi_io_rewind(VALUE obj, VALUE args) {
}
#ifdef RUBY19
#ifdef RUBY_GLOBAL_SETUP
RUBY_GLOBAL_SETUP
#endif
#endif
VALUE uwsgi_require_file(VALUE arg) {
return rb_funcall(rb_cObject, rb_intern("require"), 1, arg);
+13 -5
View File
@@ -14,7 +14,7 @@ v = version.split('.')
GCC_LIST = ['rack_plugin', 'rack_api']
if v[0] == '1' and v[1] == '9':
if (v[0] == '1' and v[1] == '9') or v[0] >= '2':
CFLAGS = os.popen(RUBYPATH + " -e \"require 'rbconfig';print RbConfig::CONFIG['CFLAGS']\"").read().rstrip().split()
CFLAGS.append('-DRUBY19')
CFLAGS.append('-Wno-unused-parameter')
@@ -34,10 +34,18 @@ else:
CFLAGS.append('-I' + archdir + '/' + arch)
CFLAGS.append('-I' + includedir + '/' + arch)
LDFLAGS = os.popen(RUBYPATH + " -e \"require 'rbconfig';print %s::CONFIG['LDFLAGS']\"" % rbconfig).read().rstrip().split()
libpath = os.popen(RUBYPATH + " -e \"require 'rbconfig';print %s::CONFIG['libdir']\"" % rbconfig).read().rstrip()
LDFLAGS.append('-L' + libpath )
os.environ['LD_RUN_PATH'] = libpath
LIBS = os.popen(RUBYPATH + " -e \"require 'rbconfig';print '-l' + %s::CONFIG['RUBY_SO_NAME']\"" % rbconfig).read().rstrip().split()
has_shared = os.popen(RUBYPATH + " -e \"require 'rbconfig';print %s::CONFIG['ENABLE_SHARED']\"" % rbconfig).read().rstrip()
LIBS = os.popen(RUBYPATH + " -e \"require 'rbconfig';print %s::CONFIG['LIBS']\"" % rbconfig).read().rstrip().split()
if has_shared == 'yes':
LDFLAGS.append('-L' + libpath )
os.environ['LD_RUN_PATH'] = libpath
LIBS.append(os.popen(RUBYPATH + " -e \"require 'rbconfig';print '-l' + %s::CONFIG['RUBY_SO_NAME']\"" % rbconfig).read().rstrip())
else:
GCC_LIST.append("%s/%s" % (libpath, os.popen(RUBYPATH + " -e \"require 'rbconfig';print %s::CONFIG['LIBRUBY_A']\"" % rbconfig).read().rstrip()))
+1 -1
View File
@@ -1,6 +1,6 @@
#include "../../uwsgi.h"
void stats_pusher_mongodb(struct uwsgi_stats_pusher_instance *, char *, size_t);
void stats_pusher_mongodb(struct uwsgi_stats_pusher_instance *, time_t, char *, size_t);
static void stats_pusher_mongodb_init(void) {
uwsgi_register_stats_pusher("mongodb", stats_pusher_mongodb);
@@ -12,7 +12,7 @@ struct stats_pusher_mongodb_conf {
};
extern "C" void stats_pusher_mongodb(struct uwsgi_stats_pusher_instance *uspi, char *json, size_t json_len) {
extern "C" void stats_pusher_mongodb(struct uwsgi_stats_pusher_instance *uspi, time_t now, char *json, size_t json_len) {
struct stats_pusher_mongodb_conf *spmc = (struct stats_pusher_mongodb_conf *) uspi->data;
if (!uspi->configured) {
+2
View File
@@ -338,6 +338,8 @@ int uwsgi_proto_http_parser(struct wsgi_request *wsgi_req) {
memcpy(post_tail, ptr, remains);
}
http_parse(wsgi_req, ptr);
wsgi_req->uh.modifier1 = uwsgi.http_modifier1;
wsgi_req->uh.modifier2 = uwsgi.http_modifier2;
//is there a Content_Length ?
if (wsgi_req->post_cl > 0) {
wsgi_req->async_post = tmpfile();
+15
View File
@@ -0,0 +1,15 @@
Gem::Specification.new do |s|
s.name = 'uwsgi'
s.license = 'GPL-2'
s.version = `python -c "import uwsgiconfig as uc; print uc.uwsgi_version"`.sub(/-dev-.*/,'')
s.date = '2013-03-02'
s.summary = "uWSGI"
s.description = "The uWSGI server for Ruby/Rack"
s.authors = ["Unbit"]
s.email = 'info@unbit.it'
s.extensions = ['ext/uwsgi/extconf.rb']
s.files = []
s.require_paths = ['.']
s.executables << 'uwsgi'
s.homepage = 'http://projects.unbit.it/uwsgi'
end
+39 -8
View File
@@ -34,8 +34,23 @@ extern "C" {
#define wsgi_req_time ((wsgi_req->end_of_request-wsgi_req->start_of_request)/1000)
#define thunder_lock if (uwsgi.threads > 1 && !uwsgi.is_et) {pthread_mutex_lock(&uwsgi.thunder_mutex);}
#define thunder_unlock if (uwsgi.threads > 1 && !uwsgi.is_et) {pthread_mutex_unlock(&uwsgi.thunder_mutex);}
#define thunder_lock if (!uwsgi.is_et) {\
if (uwsgi.use_thunder_lock) {\
uwsgi_lock(uwsgi.the_thunder_lock);\
}\
else if (uwsgi.threads > 1) {\
pthread_mutex_lock(&uwsgi.thunder_mutex);\
}\
}
#define thunder_unlock if (!uwsgi.is_et) {\
if (uwsgi.use_thunder_lock) {\
uwsgi_unlock(uwsgi.the_thunder_lock);\
}\
else if (uwsgi.threads > 1) {\
pthread_mutex_unlock(&uwsgi.thunder_mutex);\
}\
}
#define uwsgi_check_scheme(file) (!uwsgi_startswith(file, "emperor://", 10) || !uwsgi_startswith(file, "http://", 7) || !uwsgi_startswith(file, "data://", 7) || !uwsgi_startswith(file, "sym://", 6) || !uwsgi_startswith(file, "fd://", 5) || !uwsgi_startswith(file, "exec://", 7) || !uwsgi_startswith(file, "section://", 10))
@@ -295,6 +310,8 @@ extern int pivot_root(const char *new_root, const char *put_old);
#include <openssl/err.h>
#endif
#include <glob.h>
struct uwsgi_buffer {
char *buf;
@@ -928,6 +945,7 @@ struct uwsgi_alarm_ll {
struct uwsgi_alarm_log {
pcre *pattern;
pcre_extra *pattern_extra;
int negate;
struct uwsgi_alarm_ll *alarms;
struct uwsgi_alarm_log *next;
};
@@ -1291,6 +1309,9 @@ struct uwsgi_server {
int reuse_port;
uint64_t http_modifier1;
uint64_t http_modifier2;
// enable lazy mode
int lazy;
// enable lazy-apps mode
@@ -1338,6 +1359,7 @@ struct uwsgi_server {
pid_t emperor_pid;
int emperor_broodlord;
int emperor_broodlord_count;
uint64_t emperor_broodlord_num;
char *emperor_stats;
int emperor_stats_fd;
struct uwsgi_string_list *vassals_templates;
@@ -1700,9 +1722,12 @@ struct uwsgi_server {
#ifdef UWSGI_THREADING
// avoid thundering herd in threaded modes
pthread_mutex_t thunder_mutex;
pthread_mutex_t six_feet_under_lock;
pthread_mutex_t lock_static;
#endif
int use_thunder_lock;
struct uwsgi_lock_item *the_thunder_lock;
/* the list of workers */
@@ -1714,6 +1739,7 @@ struct uwsgi_server {
struct uwsgi_mule *mules;
struct uwsgi_string_list *farms_list;
struct uwsgi_farm *farms;
int mule_msg_size;
pid_t mypid;
int mywid;
@@ -1886,8 +1912,6 @@ struct uwsgi_server {
size_t queue_filesize;
int queue_store_sync;
pthread_mutex_t thunder_mutex;
int locks;
struct uwsgi_lock_item *cache_lock;
@@ -2884,6 +2908,7 @@ struct uwsgi_subscribe_slot {
void mule_send_msg(int, char *, size_t);
void create_signal_pipe(int *);
void create_msg_pipe(int *, int);
struct uwsgi_subscribe_slot *uwsgi_get_subscribe_slot(struct uwsgi_subscribe_slot **, char *, uint16_t);
struct uwsgi_subscribe_node *uwsgi_get_subscribe_node_by_name(struct uwsgi_subscribe_slot **, char *, uint16_t, char *, uint16_t);
struct uwsgi_subscribe_node *uwsgi_get_subscribe_node(struct uwsgi_subscribe_slot **, char *, uint16_t);
@@ -2955,6 +2980,7 @@ void uwsgi_opt_set_str(char *, char *, void *);
void uwsgi_opt_set_logger(char *, char *, void *);
void uwsgi_opt_set_str_spaced(char *, char *, void *);
void uwsgi_opt_add_string_list(char *, char *, void *);
void uwsgi_opt_add_string_list_custom(char *, char *, void *);
void uwsgi_opt_add_addr_list(char *, char *, void *);
void uwsgi_opt_add_dyn_dict(char *, char *, void *);
#ifdef UWSGI_PCRE
@@ -3036,6 +3062,7 @@ void uwsgi_opt_noop(char *, char *, void *);
void uwsgi_opt_logic(char *, char *, void *);
int uwsgi_logic_opt_for(char *, char *);
int uwsgi_logic_opt_for_glob(char *, char *);
int uwsgi_logic_opt_if_env(char *, char *);
int uwsgi_logic_opt_if_not_env(char *, char *);
int uwsgi_logic_opt_if_opt(char *, char *);
@@ -3131,7 +3158,7 @@ struct uwsgi_stats_pusher_instance;
struct uwsgi_stats_pusher {
char *name;
void (*func)(struct uwsgi_stats_pusher_instance *, char *, size_t);
void (*func)(struct uwsgi_stats_pusher_instance *, time_t, char *, size_t);
struct uwsgi_stats_pusher *next;
};
@@ -3139,6 +3166,7 @@ struct uwsgi_stats_pusher_instance {
struct uwsgi_stats_pusher *pusher;
char *arg;
void *data;
int raw;
int configured;
int freq;
time_t last_run;
@@ -3147,13 +3175,14 @@ struct uwsgi_stats_pusher_instance {
struct uwsgi_thread;
void uwsgi_stats_pusher_loop(struct uwsgi_thread *);
void uwsgi_stats_pusher_file(struct uwsgi_stats_pusher_instance *, char *, size_t);
void uwsgi_stats_pusher_socket(struct uwsgi_stats_pusher_instance *, char *, size_t);
void uwsgi_stats_pusher_file(struct uwsgi_stats_pusher_instance *, time_t, char *, size_t);
void uwsgi_stats_pusher_socket(struct uwsgi_stats_pusher_instance *, time_t, char *, size_t);
void uwsgi_stats_pusher_setup(void);
void uwsgi_send_stats(int, struct uwsgi_stats * (*func)(void));
struct uwsgi_stats *uwsgi_master_generate_stats(void);
void uwsgi_register_stats_pusher(char *, void(*) (struct uwsgi_stats_pusher_instance *, char *, size_t));
struct uwsgi_stats_pusher *uwsgi_register_stats_pusher(char *, void(*) (struct uwsgi_stats_pusher_instance *, time_t, char *, size_t));
struct uwsgi_stats_pusher_instance *uwsgi_stats_pusher_add(struct uwsgi_stats_pusher *, char *);
struct uwsgi_stats *uwsgi_stats_new(size_t);
int uwsgi_stats_symbol(struct uwsgi_stats *, char);
@@ -3447,6 +3476,8 @@ void simple_loop_run_int(int);
int uwsgi_valid_fd(int);
void uwsgi_close_all_fds(void);
int uwsgi_write_nb(int, char *, size_t, int);
void uwsgi_check_emperor(void);
#ifdef UWSGI_AS_SHARED_LIBRARY
int uwsgi_init(int, char **, char **);
+1 -1
View File
@@ -1,6 +1,6 @@
# uWSGI build system
uwsgi_version = '1.4.5'
uwsgi_version = '1.4.10'
import os
import re
+13 -2
View File
@@ -1,4 +1,5 @@
import uwsgi
import sys
from threading import Thread
try:
@@ -170,7 +171,12 @@ class mule_brain(object):
def __call__(self):
if uwsgi.mule_id() == self.num:
self.f()
try:
self.f()
except:
exc = sys.exc_info()
sys.excepthook(exc[0], exc[1], exc[2])
sys.exit(1)
class mule_brainloop(mule_brain):
@@ -178,7 +184,12 @@ class mule_brainloop(mule_brain):
def __call__(self):
if uwsgi.mule_id() == self.num:
while True:
self.f()
try:
self.f()
except:
exc = sys.exc_info()
sys.excepthook(exc[0], exc[1], exc[2])
sys.exit(1)
class mule(object):