Compare commits

..
84 Commits
Author SHA1 Message Date
Unbit 66099275ca updated gemspec file 2014-12-29 10:07:07 +01:00
Unbit e7a40eb173 completed backporting of fastrouter post buffering 2014-12-27 13:30:16 +01:00
Riccardo Magliocchetti 8342150b78 Fix fastrouter compilation
After 6a8f18a9bb

Fix #801
2014-12-27 13:28:41 +01:00
Roberto De Ioris e2253f3693 backport of fastrouter buffering 2014-12-27 13:28:08 +01:00
Roberto De Ioris d2f07c7583 implemented uwsgi::opt in perl 2014-12-12 07:01:28 +01:00
Roberto De Ioris 1c87053a13 implemented --pull-header 2014-12-11 15:54:21 +01:00
Unbit d69e23414f another check for mod_proxy_uwsgi 2014-12-10 10:45:06 +01:00
Roberto De Ioris 3d37d272ee fixed master-fifo + cheaper 2014-12-09 09:53:45 +01:00
Riccardo Magliocchetti 9094a0f811 Fix leak on error in bind_to_unix
Spotted by cppcheck.
2014-12-09 09:44:36 +01:00
Unbit 97efcca2b7 improved mono plugin 2014-12-04 20:55:58 +01:00
Roberto De Ioris 2445fd1f61 fixed #776 2014-12-06 10:39:27 +01:00
Unbit 3234e0aae8 fixed #680 2014-12-06 09:14:17 +01:00
Unbit c5e7eb5d95 fix #785 2014-12-05 15:22:53 +01:00
Unbit e051e4fe1c another attempt at fixing mod_proxy_uwsgi 2014-12-05 15:08:47 +01:00
Unbit 5f691ec987 attempt to fix #774 2014-12-05 09:23:55 +01:00
Unbit a8e0aac9b0 fixed #787 2014-12-05 09:11:11 +01:00
Unbit bcdbab247c fix peer name in corerouters [2] 2014-11-22 13:22:21 +01:00
Roberto De Ioris 2e378dfc29 Merge branch 'uwsgi-2.0' of github.com:unbit/uwsgi into uwsgi-2.0 2014-11-22 13:19:28 +01:00
Roberto De Ioris acc270ad81 try to fix peer name in corerouter 2014-11-22 13:12:11 +01:00
Unbit b0c3ee02f9 detect modern pypy 2014-11-21 08:35:41 +01:00
Unbit 06ab5eaee5 fix #778 2014-11-21 08:34:44 +01:00
Roberto De Ioris 46de2ae0cb attempt to fix #340 2014-11-21 06:47:04 +01:00
Unbit 65fe93ac14 fixed hr_ssl_clear_errors 2014-11-20 07:35:18 +01:00
Roberto De Ioris f7cdd22f9a attempt to fix error propagation in https 2014-11-20 07:25:19 +01:00
Andjelko Horvat 3d553d2ae0 Daemon touch kill failback. 2014-11-19 10:45:59 +01:00
Unbit 582d5828aa another round of ssl fixes 2014-11-18 19:15:29 +01:00
Unbit 245a66b0e5 try to improve ssl management 2014-11-18 18:57:59 +01:00
Roberto De Ioris 596c81124e fixed destruction 2014-11-16 20:59:45 +01:00
Unbit a86a1fcc40 added active-workers signal target, aimed at improving #58 2014-11-16 18:47:33 +01:00
Unbit 34036ac8b4 Merge branch 'uwsgi-2.0' of https://github.com/unbit/uwsgi into uwsgi-2.0 2014-11-15 13:17:56 +01:00
Unbit 11cd6c34a5 fixed python3 --py-auto-reload-ignore 2014-11-15 13:17:52 +01:00
Unbit aaea6ff2e2 fixed modifiers usage in corerouters 2014-11-15 06:32:25 +01:00
Unbit 38c30bc257 bump version to 2.0.9 2014-11-15 05:26:20 +01:00
Unbit 2f3e83b78e added httpdumb router and subscribe-with-modifier 2014-11-14 15:41:42 +01:00
Roberto De Ioris 43e8c65841 support yajl brew 2014-11-14 06:03:08 +01:00
Unbit 555902a0ee less strict http generator 2014-11-13 11:56:44 +01:00
Unbit 9d4f4eb3c3 backported #772 2014-11-12 07:43:34 +01:00
Ævar Arnfjörð Bjarmason 5d338cfb3a psgi: Ensure that we call any DESTROY hooks on psgix.harakiri.commit
Before this we'd just exit(0) and let the OS clean up after us, but
e.g. with post-buffering=1 we'll end up with a temporary file in /tmp
that we won't clean up when we exit unless DESTROY is called.

This resulted in us leaking files in /tmp if we ever had a request where
the last request before a harakiri was a POST request with a body we'd
buffer to /tmp.

We'd have similar leaks in any user-defined code that required DESTROY
to run.

Aside from this I'm still not very comfortable with what this whole code
here in psgi_plugin.c and psgi_loader.c is doing when managing the
interpreter(s). It:

 * Doesn't consistently call PERL_SET_CONTEXT() as described in "perldoc
   perlembed".

 * Nothing calls PERL_SYS_TERM() either.

 * Should we be calling uwsgi_perl_free_stashes() here too?

To test this:

    UWSGI_PROFILE=psgi python uwsgiconfig.py --build
    ./uwsgi --master --http-socket localhost:1234 --psgi t/perl/test_harakiri.psgi

Then elsewhere:

    curl 'localhost:1234?0'
    curl 'localhost:1234?1'

Both of those should emit "Calling DESTROY".
2014-11-12 07:38:18 +01:00
Riccardo Magliocchetti 3406441d95 systemdlogger: fix compilation with -Werror=format-security 2014-11-06 18:53:30 +01:00
Unbit df08c7bfb5 fixed unmasked websocket 2014-11-06 09:02:21 +01:00
Unbit 75b4a3cb28 clear if sweep_on_full fails 2014-11-05 13:06:24 +01:00
Unbit c356c01f12 Merge branch 'uwsgi-2.0' of https://github.com/unbit/uwsgi into uwsgi-2.0 2014-11-02 10:51:50 +01:00
Unbit ba8aa44baa attempt to fix #766 2014-11-02 10:51:39 +01:00
Roberto De Ioris a1dc7a660c use uwsgi_buffer for send_ack in #760 2014-11-02 09:33:07 +01:00
Roberto De Ioris 3a4663844b fixed #760 2014-11-02 06:42:53 +01:00
Mattia Barbon 309f449a43 Fix latent refcounting bug
It can be reproduced by enabling the Perl debugger inside a PSGI application:

    {
        package DB;

        sub DB { }
        sub sub { &$sub }
    }

    $^P = 0x73f;

    sub { [200, ['Content-Type' => 'text/plain'], ['Hello World']] }

For every request the following warnings are emitted:

    Attempt to free unreferenced scalar: SV 0xfea6e8, Perl interpreter: 0xd534a0.
    Attempt to free unreferenced scalar: SV 0xfea718, Perl interpreter: 0xd534a0.

where the unreferenced scalars are the uwsgi::input/uwsgi::error instances
created in build_psgi_env.

The calling convention for Perl subroutines is that the values pushed on the
stack must be mortalized in the callee, and if the caller wants to retain them,
it must do a SvREFCNT_inc to undo the effect of the mortalization.

Before this patch XS_input/XS_error were not mortalizing the value, and
uwsgi_perl_obj_new was not incrementing the reference count, so the two bugs
balanced each other.

When running under debugger, Perl forwards all function/method calls to
DB::sub, which causes a mortal copy of the return value of
uwsgi::input/error::new to be pushed on the stack. The value is cleared by the
FREETMPS at the end of uwsgi_perl_obj_new, and the freed value is added to the
environment hash. The warning is emitted at the end of the request when the
environment hash is freed and Perl notices that some of the values has been
already freed.
2014-11-02 06:13:20 +01:00
Mattia Barbon f059a69312 Remove unnecessary mortalization
newRV(sv_newmortal()) is equivalent to newRV_noinc(newSV(0)): the former
creates a new SV with refcount 1, schedules a decrement "soon" (the
mortalization) and increments the refcount, the net result is a refcount of 1,
which is what the latter does.
2014-11-02 06:13:04 +01:00
Unbit 93116a1239 prepare for 2.0.8 2014-10-26 05:30:44 +01:00
unbit 5e4440443a Merge pull request #755 from aldur/manage_script_name_fix
manage_script_name fix for tricky resources
2014-10-24 17:19:50 +02:00
Unbit 373481b888 backported rtsp support 2014-10-24 17:12:52 +02:00
Unbit 105b9c69cf backported --hook-post-fork 2014-10-24 12:07:05 +02:00
Unbit 9012ead72c backported https fix for ssl shutdown 2014-10-24 11:49:18 +02:00
Roberto De Ioris 6c1d2625a8 backported support for chunked input management in the http/https router 2014-10-19 12:54:12 +02:00
Unbit c0733b5771 Merge remote-tracking branch 'origin/uwsgi-2.0-cache-lazy-expire' into uwsgi-2.0 2014-10-18 04:23:39 +02:00
Unbit f4759d7acd fixed php SCRIPT_NAME usage when --php-app is in place 2014-10-18 04:19:41 +02:00
Unbit 7082188a06 allow appendn hook without second argument 2014-10-17 13:15:30 +02:00
Unbit bcd9ed011d try to load trollius on python2 2014-10-17 13:04:46 +02:00
Nigel Heron 25c6d7a3a1 fix heap corruption in carbon plugin 2014-10-17 05:18:58 +02:00
Roberto De Ioris 675c02c7fa fixed #749 2014-10-16 20:53:47 +02:00
Roberto De Ioris 32896a1418 fixed #748 2014-10-16 08:26:13 +02:00
Unbit 548e736d84 fixed #746 2014-10-15 10:06:27 +02:00
Unbit 87575b1a22 disable SSLv3 by default and allow setting raw ssl options 2014-10-15 09:11:18 +02:00
Roberto De Ioris 1aa6eeca1b added sweep_on_full, clear_on_full and no_expire 2014-10-14 05:24:28 +02:00
Unbit f778e30d48 run the sweeper only if required 2014-10-13 13:00:07 +02:00
Unbit e071184d53 ignore lazy caches from the sweeper 2014-10-13 12:55:26 +02:00
Unbit 1d09cde778 implemented cache lazy expire 2014-10-13 12:40:40 +02:00
Greg Dahlman 70ee29becb added wait for fs and wait for mountpoint 2014-10-10 11:06:44 +02:00
Unbit 60e26333bf allows building external plugins as embedded 2014-10-10 11:00:28 +02:00
Unbit 865b9c199d improved offload api 2014-10-10 10:58:45 +02:00
Unbit 833193a1ba added UWSGI_HAS_OFFLOAD_UBUFS 2014-10-10 10:58:41 +02:00
Unbit 4eab050634 added 8 uwsgi_buffer and 8 custom fields to offload request 2014-10-10 10:57:03 +02:00
Aldur 688d1d3b75 fixed python3 support in spooler decorators 2014-10-10 10:55:18 +02:00
Unbit 349daee614 fixed uwsgidecorators spooler arguments 2014-10-10 10:49:18 +02:00
Unbit 0d272cf747 added Adriano Di Luzio to 2.0 CONTRIBUTORS 2014-10-10 10:47:19 +02:00
Unbit 46ac28efae fixed tcsetattr 2014-10-10 10:45:58 +02:00
Unbit 31b3bcc83d fixed kevent 2014-10-10 10:45:06 +02:00
Unbit f364d676fa automatically manage HTTP_X_FORWARDED_PROTO 2014-10-10 10:40:13 +02:00
Unbit c72fde1eed ensure PSGI response headers are in the right format [2] 2014-10-03 08:32:03 +02:00
Unbit a5cacfbba6 ensure PSGI response headers are in the right format 2014-10-03 08:31:52 +02:00
Unbit 921cfa5d79 backported daemons and proto http fixes from 2.1 2014-10-03 08:30:11 +02:00
Roberto De Ioris 9c676c62f5 destroy the whole instance on Emperor error 2014-10-03 08:26:57 +02:00
Roberto De Ioris 2917de3e76 exit on Emperor error 2014-10-03 08:26:43 +02:00
Unbit e836272c07 attempt to fix #732 2014-10-03 08:26:21 +02:00
Roberto De Ioris 7e25452242 set version to 2.0.7.1 2014-09-12 06:37:06 +02:00
359 changed files with 3398 additions and 10303 deletions
-4
View File
@@ -22,7 +22,3 @@ core/dot_h.c
+# coverity
+/cov-int/
+uwsgi.tar.xz
/build/
/dist/
/uWSGI.egg-info/
+5 -4
View File
@@ -13,15 +13,15 @@ script:
- echo -e "\n\n>>> Building python27 plugin"
- /usr/bin/python2.7 -V
- /usr/bin/python2.7 uwsgiconfig.py --plugin plugins/python base python27
- echo -e "\n\n>>> Building python31 plugin"
- /usr/bin/python3.1 -V
- /usr/bin/python3.1 uwsgiconfig.py --plugin plugins/python base python31
- echo -e "\n\n>>> Building python32 plugin"
- /usr/bin/python3.2 -V
- /usr/bin/python3.2 uwsgiconfig.py --plugin plugins/python base python32
- echo -e "\n\n>>> Building python33 plugin"
- /usr/bin/python3.3 -V
- /usr/bin/python3.3 uwsgiconfig.py --plugin plugins/python base python33
- echo -e "\n\n>>> Building python34 plugin"
- /usr/bin/python3.4 -V
- /usr/bin/python3.4 uwsgiconfig.py --plugin plugins/python base python34
- echo -e "\n\n>>> Building rack 1.8.7 plugin"
- /usr/bin/ruby1.8 -v
- UWSGICONFIG_RUBYPATH=/usr/bin/ruby1.8 /usr/bin/python uwsgiconfig.py --plugin plugins/rack base rack187
@@ -36,8 +36,9 @@ script:
- ./tests/travis.sh
before_install:
- sudo add-apt-repository -y ppa:fkrull/deadsnakes
- sudo apt-get update -qq
- sudo apt-get install -qqyf rubygems1.8 ruby1.8-dev ruby1.9.1-dev
- sudo apt-get install -qqyf python2.6-dev python2.7-dev python3.1-dev python3.2-dev python3.3-dev rubygems1.8 ruby1.8-dev ruby1.9.1-dev
- sudo apt-get install -qqyf libxml2-dev libpcre3-dev libcap2-dev
- sudo apt-get install -qqyf curl
-4
View File
@@ -29,8 +29,4 @@ Danila Shtan <danila@shtan.ru>
Ævar Arnfjörð Bjarmason
Yu Zhao (getcwd)
Mathieu Dupuy
Mike Kaplinskiy
Adriano Di Luzio (adriano@unbit.it)
James Raspass
Curtis Maloney
Vladimir Didenko
+1 -1
View File
@@ -1,3 +1,3 @@
[uwsgi]
main_plugin = python,gevent,psgi,lua,php,rack,jvm,jwsgi,ring,mono,transformation_toupper,coroae,v8,cgi,xslt,webdav,ssi,ldap,gccgo,rados,pypy,zabbix,curl_cron,tornado,tuntap,pty,mongrel2,alarm_curl,router_radius,airbrake,gridfs
main_plugin = python,gevent,psgi,lua,php,rack,jvm,jwsgi,ring,mono,transformation_toupper,coroae,v8,cgi,xslt,webdav,ssi,ldap,gccgo,rados,pypy,zabbix,curl_cron,tornado,tuntap,pty,mongrel2,alarm_curl,router_radius,airbrake
inherit = base
+1 -1
View File
@@ -1,3 +1,3 @@
[uwsgi]
main_plugin = psgi,rack,lua,python,gevent,php,cgi,gccgo,glusterfs,pty,xslt,msgpack,geoip,v8,pam,ldap,mono,jvm,ring,jwsgi,servlet,rados,coroae,pypy,airbrake,alarm_curl,alarm_xmpp,asyncio,cheaper_backlog2,clock_monotonic,clock_realtime,cplusplus,curl_cron,dumbloop,dummy,echo,emperor_amqp,emperor_pg,emperor_zeromq,example,exception_log,fiber,forkptyrouter,graylog2,legion_cache_fetch,libffi,logcrypto,libtcc,logpipe,logzmq,matheval,notfound,pyuwsgi,rbthreads,router_access,router_radius,router_spnego,router_xmldir,sqlite3,ssi,stats_pusher_file,stats_pusher_statsd,systemd_logger,tornado,transformation_toupper,tuntap,webdav,xattr,zabbix
main_plugin = psgi,rack,lua,python,gevent,php,cgi,glusterfs,pty,xslt,msgpack,geoip,v8,pam,ldap,mono,jvm,ring,jwsgi,servlet,rados,coroae,pypy,gccgo
inherit = base
-1
View File
@@ -15,7 +15,6 @@ os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
CARBON_SERVER = "127.0.0.1:2003"
def update_carbon(signum):
# connect to the carbon server
carbon_fd = uwsgi.connect(CARBON_SERVER)
+4 -7
View File
@@ -12,15 +12,13 @@ import greenlet
uwsgi_pypy_greenlets = {}
def uwsgi_pypy_greenlet_wrapper():
lib.async_schedule_to_req_green()
@ffi.callback("void()")
def uwsgi_pypy_greenlet_schedule():
id = lib.uwsgi.wsgi_req.async_id
modifier1 = lib.uwsgi.wsgi_req.uh.modifier1
modifier1 = lib.uwsgi.wsgi_req.uh.modifier1;
# generate a new greenlet
if not lib.uwsgi.wsgi_req.suspended:
@@ -38,11 +36,10 @@ def uwsgi_pypy_greenlet_schedule():
if lib.uwsgi.p[modifier1].resume:
lib.uwsgi.p[modifier1].resume(ffi.NULL)
@ffi.callback("void(struct wsgi_request *)")
def uwsgi_pypy_greenlet_switch(wsgi_req):
wsgi_req.async_id
modifier1 = wsgi_req.uh.modifier1
id = wsgi_req.async_id
modifier1 = wsgi_req.uh.modifier1;
# this is called in the current greenlet
if lib.uwsgi.p[modifier1].suspend:
@@ -57,7 +54,7 @@ def uwsgi_pypy_greenlet_switch(wsgi_req):
# update current running greenlet
lib.uwsgi.wsgi_req = wsgi_req
if lib.uwsgi.async < 1:
if lib.uwsgi.async <= 1:
raise Exception("pypy greenlets require async mode !!!")
lib.uwsgi.schedule_to_main = uwsgi_pypy_greenlet_switch
lib.uwsgi.schedule_to_req = uwsgi_pypy_greenlet_schedule
+1 -1
View File
@@ -11,7 +11,7 @@ uwsgi_args = []
for arg in sys.argv[2:]:
uwsgi_args.append(arg)
# pyuwsgi.run('welcome.ini')
#pyuwsgi.run('welcome.ini')
pyuwsgi.run(uwsgi_args)
# if you are here uWSGI has been reloaded
+4 -5
View File
@@ -4,7 +4,6 @@ from django.conf import settings
import os
import sys
class Command(BaseCommand):
help = "Runs this project as a uWSGI application. Requires the uwsgi binary in system path."
@@ -13,10 +12,10 @@ class Command(BaseCommand):
def handle(self, *args, **options):
for arg in args:
k, v = arg.split('=')
k,v = arg.split('=')
if k == 'http':
if self.http_port:
self.http_port = v
self.http_port = v
elif k == 'socket':
self.http_port = None
self.socket_addr = v
@@ -41,8 +40,8 @@ class Command(BaseCommand):
elif self.socket_addr:
os.environ['UWSGI_SOCKET'] = self.socket_addr
# map admin static files
os.environ['UWSGI_STATIC_MAP'] = '%s=%s' % (settings.ADMIN_MEDIA_PREFIX, os.path.join(django.__path__[0], 'contrib', 'admin', 'media'))
# map admin static files
os.environ['UWSGI_STATIC_MAP'] = '%s=%s' % (settings.ADMIN_MEDIA_PREFIX, os.path.join(django.__path__[0], 'contrib', 'admin', 'media'))
# remove sockets/pidfile at exit
os.environ['UWSGI_VACUUM'] = '1'
# retrieve/set the PythonHome
+3 -2
View File
@@ -1,10 +1,11 @@
from tasksconsumer import enqueue
def application(env, sr):
sr('200 OK', [('Content-Type', 'text/html')])
sr('200 OK', [('Content-Type','text/html')])
enqueue(queue='fast', pippo='pluto')
return "Task enqueued"
+1 -3
View File
@@ -1,11 +1,9 @@
from tasksconsumer import queueconsumer
from tasksconsumer import *
@queueconsumer('fast', 4)
def fast_queue(arguments):
print "fast", arguments
@queueconsumer('slow')
def slow_queue(arguments):
print "foobar", arguments
+14 -15
View File
@@ -1,36 +1,35 @@
from uwsgidecorators import spool
from uwsgidecorators import *
import Queue
from threading import Thread
queues = {}
class queueconsumer(object):
def __init__(self, name, num=1, **kwargs):
self.name = name
self.num = num
self.num = num
self.queue = Queue.Queue()
self.threads = []
self.func = None
queues[self.name] = self
self.threads = []
self.func = None
queues[self.name] = self
@staticmethod
def consumer(self):
while True:
req = self.queue.get()
req = self.queue.get()
print req
self.func(req)
self.queue.task_done()
self.func(req)
self.queue.task_done()
def __call__(self, f):
self.func = f
for i in range(self.num):
t = Thread(target=self.consumer, args=(self,))
self.threads.append(t)
t.daemon = True
t.start()
for i in range(self.num):
t = Thread(target=self.consumer,args=(self,))
self.threads.append(t)
t.daemon = True
t.start()
@spool
def spooler_enqueuer(arguments):
+52 -51
View File
@@ -1,22 +1,22 @@
from twisted.internet import defer, protocol, reactor
from twisted.protocols import basic
from twisted.web2 import http, resource, responsecode, stream
from twisted.web2 import server, http, resource, responsecode, stream, channel
from twisted.application import service, strports
import struct
class uWSGIClientResource(resource.LeafResource):
def __init__(self, app='', port=3030, host='localhost'):
def __init__(self,app='', port=3030, host='localhost'):
resource.LeafResource.__init__(self)
self.host = host
self.port = port
self.app = app
self.app = app
def renderHTTP(self, request):
return uWSGI(request, self.app, self.host, self.port)
def uWSGI(request, app, host, port):
if request.stream.length is None:
return http.Response(responsecode.LENGTH_REQUIRED)
@@ -25,59 +25,60 @@ def uWSGI(request, app, host, port):
factory = uWSGIClientProtocolFactory(request)
reactor.connectTCP(host, port, factory)
return factory.deferred
class uWSGIClientProtocol(basic.LineReceiver):
def __init__(self, request, deferred):
self.request = request
self.deferred = deferred
self.stream = stream.ProducerStream()
self.response = http.Response(stream=self.stream)
self.status_parsed = None
self.status_parsed = None
def build_uwsgi_var(self, key, value):
return struct.pack('<H', len(key)) + key + struct.pack('<H', len(value)) + value
def build_uwsgi_var(self,key,value):
return struct.pack('<H',len(key)) + key + struct.pack('<H',len(value)) + value
def connectionMade(self):
print(self.request.__dict__)
# reset response parser
self.status_parsed = None
# build header and vars
vars = ''
print self.request.__dict__
# reset response parser
self.status_parsed = None
# build header and vars
vars = ''
if self.request.stream.length:
vars += self.build_uwsgi_var('CONTENT_LENGTH', str(self.request.stream.length))
if self.request.stream.length:
vars += self.build_uwsgi_var('CONTENT_LENGTH',str(self.request.stream.length))
for hkey, hval in self.request.headers.getAllRawHeaders():
# use a list, probably it will be extended
if hkey.lower() not in ('content-type'):
vars += self.build_uwsgi_var('HTTP_' + hkey.upper().replace('-', '_'), ','.join(hval))
else:
vars += self.build_uwsgi_var(hkey.upper().replace('-', '_'), ','.join(hval))
for hkey, hval in self.request.headers.getAllRawHeaders():
# use a list, probably it will be extended
if hkey.lower() not in ('content-type'):
vars += self.build_uwsgi_var('HTTP_'+hkey.upper().replace('-','_'),','.join(hval))
else:
vars += self.build_uwsgi_var(hkey.upper().replace('-','_'),','.join(hval))
vars += self.build_uwsgi_var('REQUEST_METHOD', self.request.method)
vars += self.build_uwsgi_var('SCRIPT_NAME', self.request.uwsgi_app)
vars += self.build_uwsgi_var('PATH_INFO', self.request.path[len(self.request.uwsgi_app):])
vars += self.build_uwsgi_var('QUERY_STRING', self.request.querystring)
vars += self.build_uwsgi_var('SERVER_NAME', self.request.host)
vars += self.build_uwsgi_var('SERVER_PORT', str(self.request.port))
vars += self.build_uwsgi_var('SERVER_PROTOCOL', self.request.scheme.upper() + '/' + str(self.request.clientproto[0]) + '.' + str(self.request.clientproto[1]))
vars += self.build_uwsgi_var('REQUEST_METHOD', self.request.method)
vars += self.build_uwsgi_var('SCRIPT_NAME', self.request.uwsgi_app)
vars += self.build_uwsgi_var('PATH_INFO', self.request.path[len(self.request.uwsgi_app):])
vars += self.build_uwsgi_var('QUERY_STRING', self.request.querystring)
vars += self.build_uwsgi_var('SERVER_NAME', self.request.host)
vars += self.build_uwsgi_var('SERVER_PORT', str(self.request.port))
vars += self.build_uwsgi_var('SERVER_PROTOCOL', self.request.scheme.upper()+'/'+str(self.request.clientproto[0]) +'.'+str(self.request.clientproto[1]))
vars += self.build_uwsgi_var('REQUEST_URI', self.request.uri)
vars += self.build_uwsgi_var('REMOTE_ADDR', self.request.remoteAddr.host)
vars += self.build_uwsgi_var('REQUEST_URI', self.request.uri)
vars += self.build_uwsgi_var('REMOTE_ADDR', self.request.remoteAddr.host)
self.transport.write(struct.pack('<BHB', 0, len(vars), 0))
self.transport.write(vars)
# send request data
self.transport.write(struct.pack('<BHB',0, len(vars),0))
self.transport.write(vars)
# send request data
stream.StreamProducer(self.request.stream).beginProducing(self.transport)
def lineReceived(self, line):
if self.status_parsed is None:
self.response.code = line.split(' ', 2)[1]
self.status_parsed = True
return
if self.status_parsed is None:
self.response.code = line.split(' ',2)[1]
self.status_parsed = True
return
# end of headers
if line == '':
@@ -86,33 +87,33 @@ class uWSGIClientProtocol(basic.LineReceiver):
self.response = None
return
name, value = line.split(':', 1)
name, value = line.split(':',1)
value = value.strip()
self.response.headers.addRawHeader(name, value)
def rawDataReceived(self, data):
self.stream.write(data)
def connectionLost(self, reason):
self.stream.finish()
class uWSGIClientProtocolFactory(protocol.ClientFactory):
protocol = uWSGIClientProtocol
noisy = False # Make Factory shut up
noisy = False # Make Factory shut up
def __init__(self, request):
self.request = request
self.deferred = defer.Deferred()
def buildProtocol(self, addr):
return self.protocol(self.request, self.deferred)
def clientConnectionFailed(self, connector, reason):
self.sendFailureResponse(reason)
def sendFailureResponse(self, reason):
response = http.Response(code=responsecode.BAD_GATEWAY, stream=str(reason.value))
self.deferred.callback(response)
+26 -48
View File
@@ -6,7 +6,6 @@ import time
import sys
from optparse import OptionParser
class Cache:
def __init__(self, filename, cache_slots, block_size=65536, sample_sleep=1):
@@ -42,7 +41,7 @@ class Cache:
fields = struct.unpack_from('@HHIQQQQQ2048c', buf)
key = array.array('c', fields[8:self.key_size+8]).tostring().rstrip('\x00')
if [x for x in key if x != '\x00']:
if [x for x in key if x!= '\x00']:
buf = self.store_read_item_block(position)
value = array.array('c', buf).tostring().rstrip('\x00')
else:
@@ -56,7 +55,7 @@ class Cache:
if self.sample_sleep:
time.sleep(self.sample_sleep)
return data
def update_stats(self, data):
# data is a list of (position, key, value, len(value)) tuples
items = len([1 for x in data if x[3] > 0])
@@ -69,75 +68,54 @@ class Cache:
self.samples += 1
block_sizes = sum([x[3] for x in data])
self.block_sizes += block_sizes
self.history.append({
'full': full,
'empty': empty,
'data': data,
'items': items,
'block_sizes': block_sizes
})
self.history.append({'full': full, 'empty': empty, 'data': data, \
'items': items, 'block_sizes': block_sizes})
def dump(self):
return {
'samples': self.samples,
'history': self.history,
'cache_slots': self.cache_slots,
'sample_sleep': self.sample_sleep,
'sample_sleep': self.sample_sleep,
'cache_empty': self.cache_empty,
'cache_full': self.cache_full,
'cache_items': self.cache_items,
'block_sizes': self.block_sizes,
}
}
def show_dump(self):
d = self.dump()
print()
print("Recorded %d samples (%d second(s) sleep between samples)" % (
d['samples'],
d['sample_sleep']
))
print("Cache empty %d times, full %d times, %.2f items on average" % (
d['cache_empty'],
d['cache_full'],
d['cache_items'] / d['samples']
))
print("Block size average size: %d bytes" % (
d['block_sizes'] / d['cache_items'] * 8
))
print("Data in cache average: %d bytes" % (
d['block_sizes'] / d['samples'] * 8
))
print
print "Recorded %d samples (%d second(s) sleep between samples)" % \
(d['samples'], d['sample_sleep'])
print "Cache empty %d times, full %d times, %.2f items on average" % \
(d['cache_empty'], d['cache_full'], d['cache_items'] / d['samples'])
print "Block size average size: %d bytes" % \
(d['block_sizes'] / d['cache_items'] * 8)
print "Data in cache average: %d bytes" % \
(d['block_sizes'] / d['samples'] * 8)
def main(options):
cache = Cache(options.cache_store, options.cache_slots, options.block_size,
options.sleep_time)
print("Recording...")
options.sleep_time)
print "Recording..."
while True:
try:
cache.read()
data = cache.read()
except KeyboardInterrupt:
cache.show_dump()
sys.exit(0)
if __name__ == '__main__':
parser = OptionParser()
parser.add_option(
"-s", "--cache-slots", dest="cache_slots", type="int",
help="Slots available in the cache, uwsgi cache option"
)
parser.add_option(
"-c", "--cache-store", dest="cache_store", default="uwsgi.cache",
help="The filename of the cache store, uwsgi cache-store option. Default: uwsgi.cache"
)
parser.add_option(
"-b", "--block-size", dest="block_size", default=65536, type="int",
help="The size of the cache block, uwsgi cache-blocksize option. Default: 65536"
)
parser.add_option(
"-t", "--sleep-time", dest="sleep_time", default=1, type="int",
help="The time to sleep between each sample. Default: 1"
)
parser.add_option("-s", "--cache-slots", dest="cache_slots", type="int",
help="Slots available in the cache, uwsgi cache option")
parser.add_option("-c", "--cache-store", dest="cache_store", default="uwsgi.cache",
help="The filename of the cache store, uwsgi cache-store option. Default: uwsgi.cache")
parser.add_option("-b", "--block-size", dest="block_size", default=65536, type="int",
help="The size of the cache block, uwsgi cache-blocksize option. Default: 65536")
parser.add_option("-t", "--sleep-time", dest="sleep_time", default=1, type="int",
help="The time to sleep between each sample. Default: 1")
(options, args) = parser.parse_args()
if not options.cache_slots:
-1
View File
@@ -171,7 +171,6 @@ static int uwsgi_alarm_log_add(char *alarms, char *regexp, int negate) {
ual = uwsgi_calloc(sizeof(struct uwsgi_alarm_log));
if (uwsgi_regexp_build(regexp, &ual->pattern, &ual->pattern_extra)) {
free(ual);
return -1;
}
ual->negate = negate;
+8 -12
View File
@@ -21,7 +21,7 @@ extern struct uwsgi_server uwsgi;
// this is called whenever a new connection is ready, but there are no cores to handle it
void uwsgi_async_queue_is_full(time_t now) {
if (now > uwsgi.async_queue_is_full && uwsgi.async_warn_if_queue_full) {
if (now > uwsgi.async_queue_is_full) {
uwsgi_log_verbose("[DANGER] async queue is full !!!\n");
uwsgi.async_queue_is_full = now;
}
@@ -165,7 +165,7 @@ static void async_expire_timeouts(uint64_t now) {
int async_add_fd_read(struct wsgi_request *wsgi_req, int fd, int timeout) {
if (uwsgi.async < 1 || !uwsgi.async_waiting_fd_table){
if (uwsgi.async < 2 || !uwsgi.async_waiting_fd_table){
uwsgi_log_verbose("ASYNC call without async mode !!!\n");
return -1;
}
@@ -257,7 +257,7 @@ static int async_wait_fd_read2(int fd0, int fd1, int timeout, int *fd) {
void async_add_timeout(struct wsgi_request *wsgi_req, int timeout) {
if (uwsgi.async < 1 || !uwsgi.rb_async_timeouts) {
if (uwsgi.async < 2 || !uwsgi.rb_async_timeouts) {
uwsgi_log_verbose("ASYNC call without async mode !!!\n");
return;
}
@@ -272,7 +272,7 @@ void async_add_timeout(struct wsgi_request *wsgi_req, int timeout) {
int async_add_fd_write(struct wsgi_request *wsgi_req, int fd, int timeout) {
if (uwsgi.async < 1 || !uwsgi.async_waiting_fd_table) {
if (uwsgi.async < 2 || !uwsgi.async_waiting_fd_table) {
uwsgi_log_verbose("ASYNC call without async mode !!!\n");
return -1;
}
@@ -370,7 +370,7 @@ void async_schedule_to_req_green(void) {
}
// switch after each yield
if (uwsgi.schedule_to_main)
uwsgi.schedule_to_main(wsgi_req);
uwsgi.schedule_to_main(wsgi_req);
}
#ifdef UWSGI_ROUTING
@@ -385,6 +385,7 @@ end:
wsgi_req->async_status = UWSGI_OK;
uwsgi.async_queue_unused_ptr++;
uwsgi.async_queue_unused[uwsgi.async_queue_unused_ptr] = wsgi_req;
}
static int uwsgi_async_wait_milliseconds_hook(int timeout) {
@@ -406,7 +407,7 @@ static int uwsgi_async_wait_milliseconds_hook(int timeout) {
void async_loop() {
if (uwsgi.async < 1) {
if (uwsgi.async < 2) {
uwsgi_log("the async loop engine requires async mode (--async <n>)\n");
exit(1);
}
@@ -481,12 +482,7 @@ void async_loop() {
// signals are executed in the main stack... in the future we could have dedicated stacks for them
if (uwsgi.signal_socket > -1 && (interesting_fd == uwsgi.signal_socket || interesting_fd == uwsgi.my_signal_socket)) {
uwsgi.wsgi_req = find_first_available_wsgi_req();
if (uwsgi.wsgi_req == NULL) {
uwsgi_async_queue_is_full((time_t)now);
continue;
}
uwsgi_receive_signal(uwsgi.wsgi_req, interesting_fd, "worker", uwsgi.mywid);
uwsgi_receive_signal(interesting_fd, "worker", uwsgi.mywid);
continue;
}
-33
View File
@@ -150,32 +150,6 @@ int uwsgi_buffer_append_json(struct uwsgi_buffer *ub, char *buf, size_t len) {
return 0;
}
int uwsgi_buffer_append_xml(struct uwsgi_buffer *ub, char *buf, size_t len) {
// need to escape \ and "
size_t i;
for(i=0;i<len;i++) {
if (buf[i] == '"') {
if (uwsgi_buffer_append(ub, "&quot;", 6)) return -1;
}
else if (buf[i] == '\'') {
if (uwsgi_buffer_append(ub, "&apos;", 6)) return -1;
}
else if (buf[i] == '<') {
if (uwsgi_buffer_append(ub, "&lt;", 4)) return -1;
}
else if (buf[i] == '>') {
if (uwsgi_buffer_append(ub, "&gt;", 4)) return -1;
}
else if (buf[i] == '&') {
if (uwsgi_buffer_append(ub, "&amp;", 5)) return -1;
}
else {
if (uwsgi_buffer_append(ub, buf+i, 1)) return -1;
}
}
return 0;
}
int uwsgi_buffer_u16le(struct uwsgi_buffer *ub, uint16_t num) {
uint8_t buf[2];
buf[0] = (uint8_t) (num & 0xff);
@@ -444,10 +418,3 @@ void uwsgi_buffer_map(struct uwsgi_buffer *ub, char *buf, size_t len) {
ub->pos = len;
ub->len = len;
}
int uwsgi_buffer_httpdate(struct uwsgi_buffer *ub, time_t t) {
char http_last_modified[49];
int size = uwsgi_http_date(t, http_last_modified);
if (size <= 0) return -1;
return uwsgi_buffer_append(ub, http_last_modified, size);
}
+13 -5
View File
@@ -26,6 +26,7 @@ extern struct uwsgi_server uwsgi;
static void cache_full(struct uwsgi_cache *uc) {
uint64_t i;
int force_clear = 0;
if (!uc->ignore_full) {
if (uc->purge_lru)
@@ -41,19 +42,25 @@ static void cache_full(struct uwsgi_cache *uc) {
// we do not need locking here !
if (uc->sweep_on_full) {
uint64_t removed = 0;
uint64_t now = (uint64_t) uwsgi_now();
if (uc->next_scan <= now) {
uc->next_scan = now + uc->sweep_on_full;
for (i = 1; i < uc->max_items; i++) {
struct uwsgi_cache_item *uci = cache_item(i);
if (uci->expires > 0 && uci->expires <= now) {
uwsgi_cache_del2(uc, NULL, 0, i, 0);
if (!uwsgi_cache_del2(uc, NULL, 0, i, 0)) {
removed++;
}
}
}
if (removed == 0) {
force_clear = 1;
}
}
}
if (uc->clear_on_full) {
if (uc->clear_on_full || force_clear) {
for (i = 1; i < uc->max_items; i++) {
uwsgi_cache_del2(uc, NULL, 0, i, 0);
}
@@ -242,6 +249,7 @@ static void uwsgi_cache_add_items(struct uwsgi_cache *uc) {
goto next;
}
key = space+1;
key_len = usl->len - ((space-usl->value)+1);
}
char *value = strchr(key, '=');
if (!value) {
@@ -971,7 +979,7 @@ static void cache_send_udp_command(struct uwsgi_cache *uc, char *key, uint16_t k
iov[2].iov_base = key;
iov[2].iov_len = keylen;
uh._pktsize = 2 + keylen;
uh.pktsize = 2 + keylen;
if (cmd == 10) {
u_v[0] = (uint8_t) (vallen16 & 0xff);
@@ -995,7 +1003,7 @@ static void cache_send_udp_command(struct uwsgi_cache *uc, char *key, uint16_t k
iov[6].iov_base = es;
iov[6].iov_len = es_size;
uh._pktsize += 2 + vallen16 + 2 + es_size;
uh.pktsize += 2 + vallen16 + 2 + es_size;
}
uh.modifier1 = 111;
@@ -2041,7 +2049,7 @@ void uwsgi_cache_sync_from_nodes(struct uwsgi_cache *uc) {
struct uwsgi_buffer *ub = uwsgi_buffer_new(uwsgi.page_size + uc->filesize);
ub->pos = 4;
if (uc->name && uwsgi_buffer_append(ub, uc->name, uc->name_len)) {
if (uwsgi_buffer_append(ub, uc->name, uc->name_len)) {
uwsgi_buffer_destroy(ub);
close(fd);
goto next;
+159 -578
View File
File diff suppressed because it is too large Load Diff
+4 -3
View File
@@ -46,7 +46,7 @@ extern struct uwsgi_server uwsgi;
struct uwsgi_buffer *uwsgi_exception_handler_object(struct wsgi_request *wsgi_req) {
struct uwsgi_buffer *ub = uwsgi_buffer_new(4096);
if (uwsgi_buffer_append_keyval(ub, "vars", 4, wsgi_req->buffer, wsgi_req->len)) goto error;
if (uwsgi_buffer_append_keyval(ub, "vars", 4, wsgi_req->buffer,wsgi_req->uh->pktsize)) goto error;
if (uwsgi.p[wsgi_req->uh->modifier1]->backtrace) {
struct uwsgi_buffer *bt = uwsgi.p[wsgi_req->uh->modifier1]->backtrace(wsgi_req);
if (bt) {
@@ -280,7 +280,7 @@ notavail4:
if (uwsgi_buffer_append(ub, "\n\n", 2)) goto error;
if (uwsgi_hooked_parse(wsgi_req->buffer, wsgi_req->len, append_vars_to_ubuf, ub)) {
if (uwsgi_hooked_parse(wsgi_req->buffer, wsgi_req->uh->pktsize, append_vars_to_ubuf, ub)) {
goto error;
}
@@ -464,7 +464,6 @@ void uwsgi_exception_setup_handlers() {
struct uwsgi_string_list *usl = uwsgi.exception_handlers_instance;
while(usl) {
// do not free handler !!!
char *handler = uwsgi_str(usl->value);
char *colon = strchr(handler, ':');
if (colon) {
@@ -473,8 +472,10 @@ void uwsgi_exception_setup_handlers() {
struct uwsgi_exception_handler *ueh = uwsgi_exception_handler_by_name(handler);
if (!ueh) {
uwsgi_log("unable to find exception handler: %s\n", handler);
free(handler);
exit(1);
}
free(handler);
struct uwsgi_exception_handler_instance *uehi = uwsgi_calloc(sizeof(struct uwsgi_exception_handler_instance));
uehi->handler = ueh;
-227
View File
@@ -1,227 +0,0 @@
#include <uwsgi.h>
extern struct uwsgi_server uwsgi;
/*
on connection retrieve the uid,gid and pid of the connecting process, in addition to up to 3
file descriptors (emperor pipe, emperor pipe_config, on_demand socket dup()'ed to 0)
if authorized, double fork, get the pid of the second child and exit()
its parent (this will force the Emperor to became its subreaper).
from now on, we can consider the new child as a full-featured vassal
*/
#define VASSAL_HAS_CONFIG 0x02
#define VASSAL_HAS_ON_DEMAND 0x04
static void parse_argv_hook(uint16_t item, char *value, uint16_t vlen, void *data) {
struct uwsgi_string_list **usl = (struct uwsgi_string_list **) data;
uwsgi_string_new_list(usl, uwsgi_concat2n(value, vlen, "", 0));
}
void uwsgi_fork_server(char *socket) {
// map fd 0 to /dev/null to avoid mess
uwsgi_remap_fd(0, "/dev/null");
int fd = bind_to_unix(socket, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
if (fd < 0) exit(1);
// automatically receive credentials (TODO make something useful with them, like checking the pid is from the Emperor)
if (uwsgi_socket_passcred(fd)) exit(1);
// initialize the event queue
int eq = event_queue_init();
if (uwsgi.has_emperor) {
event_queue_add_fd_read(eq, uwsgi.emperor_fd);
}
event_queue_add_fd_read(eq, fd);
// now start waiting for connections
for(;;) {
int interesting_fd = -1;
int rlen = event_queue_wait(eq, -1, &interesting_fd);
if (rlen <= 0) continue;
if (uwsgi.has_emperor && interesting_fd == uwsgi.emperor_fd) {
char byte;
ssize_t rlen = read(uwsgi.emperor_fd, &byte, 1);
if (rlen > 0) {
uwsgi_log_verbose("received message %d from emperor\n", byte);
}
exit(0);
}
if (interesting_fd != fd) continue;
struct sockaddr_un client_src;
socklen_t client_src_len = 0;
int client_fd = accept(fd, (struct sockaddr *) &client_src, &client_src_len);
if (client_fd < 0) {
uwsgi_error("uwsgi_fork_server()/accept()");
continue;
}
char hbuf[4];
pid_t ppid = -1;
uid_t uid = -1;
gid_t gid = -1;
int fds_count = 8;
size_t remains = 4;
// we can receive upto 8 fds (generally from 1 to 3)
int fds[8];
// we only read 4 bytes header
ssize_t len = uwsgi_recv_cred_and_fds(client_fd, hbuf, remains, &ppid, &uid, &gid, fds, &fds_count);
uwsgi_log_verbose("[uwsgi-fork-server] connection from pid: %d uid: %d gid:%d fds:%d\n", ppid, uid, gid, fds_count);
if (len <= 0 || fds_count < 1) {
uwsgi_error("uwsgi_fork_server()/recvmsg()");
goto end;
}
remains -= len;
if (uwsgi_read_nb(client_fd, hbuf + (4-remains), remains, uwsgi.socket_timeout)) {
uwsgi_error("uwsgi_fork_server()/uwsgi_read_nb()");
goto end;
}
struct uwsgi_header *uh = (struct uwsgi_header *) hbuf;
// this memory area must be freed in the right place !!!
char *body_argv = uwsgi_malloc(uh->_pktsize);
if (uwsgi_read_nb(client_fd, body_argv, uh->_pktsize, uwsgi.socket_timeout)) {
free(body_argv);
uwsgi_error("uwsgi_fork_server()/uwsgi_read_nb()");
goto end;
}
pid_t pid = fork();
if (pid < 0) {
free(body_argv);
int i;
for(i=0;i<fds_count;i++) close(fds[i]);
// error on fork()
uwsgi_error("uwsgi_fork_server()/fork()");
goto end;
}
else if (pid > 0) {
free(body_argv);
// close inherited decriptors
int i;
for(i=0;i<fds_count;i++) close(fds[i]);
// wait for child death...
waitpid(pid, NULL, 0);
goto end;
}
else {
// close Emperor channels
// we do not close others file desctiptor as lot
// of funny tricks could be accomplished with them
if (uwsgi.has_emperor) {
close(uwsgi.emperor_fd);
if (uwsgi.emperor_fd_config > -1) close(uwsgi.emperor_fd_config);
}
// set EMPEROR_FD and FD_CONFIG env vars
char *uef = uwsgi_num2str(fds[0]);
if (setenv("UWSGI_EMPEROR_FD", uef, 1)) {
uwsgi_error("uwsgi_fork_server()/setenv()");
exit(1);
}
free(uef);
int pipe_config = -1;
int on_demand = -1;
if (uh->modifier2 & VASSAL_HAS_CONFIG && fds_count > 1) {
pipe_config = fds[1];
char *uef = uwsgi_num2str(pipe_config);
if (setenv("UWSGI_EMPEROR_FD_CONFIG", uef, 1)) {
uwsgi_error("uwsgi_fork_server()/setenv()");
exit(1);
}
free(uef);
}
if (uh->modifier2 & VASSAL_HAS_ON_DEMAND && fds_count > 1) {
if (pipe_config > -1) {
if (fds_count > 2) {
on_demand = fds[2];
}
}
else {
on_demand = fds[1];
}
}
// dup the on_demand socket to 0 and close it
if (on_demand > -1) {
if (dup2(on_demand, 0) < 0) {
uwsgi_error("uwsgi_fork_server()/dup2()");
exit(1);
}
close(on_demand);
}
// now fork again and die
pid_t new_pid = fork();
if (new_pid < 0) {
uwsgi_error("uwsgi_fork_server()/fork()");
exit(1);
}
else if (new_pid > 0) {
exit(0);
}
else {
// send the pid to the client_fd and close it
struct uwsgi_buffer *ub = uwsgi_buffer_new(uwsgi.page_size);
// leave space for header
ub->pos = 4;
if (uwsgi_buffer_append_keynum(ub, "pid", 3, getpid())) exit(1);
// fix uwsgi header
if (uwsgi_buffer_set_uh(ub, 35, 0)) goto end;
// send_pid()
if (uwsgi_write_nb(client_fd, ub->buf, ub->pos, uwsgi.socket_timeout)) exit(1);
close(client_fd);
uwsgi_log("double fork() and reparenting successfull (new pid: %d)\n", getpid());
uwsgi_buffer_destroy(ub);
// now parse the uwsgi packet array and build the argv
struct uwsgi_string_list *usl = NULL, *usl_argv = NULL;
uwsgi_hooked_parse_array(body_argv, uh->_pktsize, parse_argv_hook, &usl_argv);
free(body_argv);
// build new argc/argv
uwsgi.new_argc = 0;
size_t procname_len = 1;
uwsgi_foreach(usl, usl_argv) {
uwsgi.new_argc++;
procname_len += usl->len + 1;
}
char *new_procname = uwsgi_calloc(procname_len);
uwsgi.new_argv = uwsgi_calloc(sizeof(char *) * (uwsgi.new_argc + 1));
int counter = 0;
uwsgi_foreach(usl, usl_argv) {
uwsgi.new_argv[counter] = usl->value;
strcat(new_procname, usl->value);
strcat(new_procname, " ");
counter++;
}
// fix process name
uwsgi_set_processname(new_procname);
free(new_procname);
// this is the only step required to have a consistent environment
uwsgi.fork_socket = NULL;
// this avoids the process to re-exec itself
uwsgi.exit_on_reload = 1;
// fixup the Emperor communication
uwsgi_check_emperor();
// continue with uWSGI startup
return;
}
}
end:
close(client_fd);
}
}
+10 -3
View File
@@ -61,9 +61,16 @@ static void fsmon_reload(struct uwsgi_fsmon *fs) {
}
static void fsmon_brutal_reload(struct uwsgi_fsmon *fs) {
uwsgi_block_signal(SIGQUIT);
reap_them_all(0);
uwsgi_unblock_signal(SIGQUIT);
if (uwsgi.die_on_term) {
uwsgi_block_signal(SIGQUIT);
reap_them_all(0);
uwsgi_unblock_signal(SIGQUIT);
}
else {
uwsgi_block_signal(SIGTERM);
reap_them_all(0);
uwsgi_unblock_signal(SIGTERM);
}
}
static void fsmon_signal(struct uwsgi_fsmon *fs) {
+1 -1
View File
@@ -72,7 +72,7 @@ void gateway_respawn(int id) {
if (gw_pid == 0) {
uwsgi_fixup_fds(0, 0, ug);
uwsgi_close_all_unshared_sockets();
uwsgi_close_all_sockets();
if (uwsgi.master_as_root)
uwsgi_as_root();
#ifdef __linux__
+42 -212
View File
@@ -91,14 +91,6 @@ static int uwsgi_hook_exec(char *arg) {
return ret;
}
static int uwsgi_hook_safeexec(char *arg) {
int ret = uwsgi_run_command_and_wait(NULL, arg);
if (ret != 0) {
uwsgi_log("command \"%s\" exited with non-zero code: %d\n", arg, ret);
}
return 0;
}
static int uwsgi_hook_exit(char *arg) {
int exit_code = 0;
if (strlen(arg) > 1) {
@@ -396,10 +388,9 @@ static int uwsgi_hook_chown2(char *arg) {
}
#if defined(UWSGI_SUNOS_EXTERN_SETHOSTNAME)
#ifdef __sun__
extern int sethostname(char *, int);
#endif
static int uwsgi_hook_hostname(char *arg) {
#ifdef __CYGWIN__
return -1;
@@ -408,24 +399,6 @@ static int uwsgi_hook_hostname(char *arg) {
#endif
}
static int uwsgi_hook_unix_signal(char *arg) {
char *space = strchr(arg, ' ');
if (!space) {
uwsgi_log("invalid unix_signal syntax, must be <signum> <func>\n");
return -1;
}
*space = 0;
int signum = atoi(arg);
*space = ' ';
void (*func)(int) = dlsym(RTLD_DEFAULT, space+1);
if (!func) {
uwsgi_log("unable to find function \"%s\"\n", space+1);
return -1;
}
uwsgi_unix_signal(signum, func);
return 0;
}
static int uwsgi_hook_callint(char *arg) {
char *space = strchr(arg, ' ');
@@ -576,22 +549,6 @@ static int uwsgi_hook_retryrpc(char *arg) {
return 0;
}
static int uwsgi_hook_wait_for_fs(char *arg) {
return uwsgi_wait_for_fs(arg, 0);
}
static int uwsgi_hook_wait_for_file(char *arg) {
return uwsgi_wait_for_fs(arg, 1);
}
static int uwsgi_hook_wait_for_dir(char *arg) {
return uwsgi_wait_for_fs(arg, 2);
}
static int uwsgi_hook_wait_for_socket(char *arg) {
return uwsgi_wait_for_socket(arg);
}
void uwsgi_register_base_hooks() {
uwsgi_register_hook("cd", uwsgi_hook_chdir);
uwsgi_register_hook("chdir", uwsgi_hook_chdir);
@@ -605,7 +562,6 @@ void uwsgi_register_base_hooks() {
uwsgi_register_hook("sticky", uwsgi_hook_sticky);
uwsgi_register_hook("exec", uwsgi_hook_exec);
uwsgi_register_hook("safeexec", uwsgi_hook_safeexec);
uwsgi_register_hook("create", uwsgi_hook_creat);
uwsgi_register_hook("creat", uwsgi_hook_creat);
@@ -633,187 +589,61 @@ void uwsgi_register_base_hooks() {
uwsgi_register_hook("rpc", uwsgi_hook_rpc);
uwsgi_register_hook("retryrpc", uwsgi_hook_retryrpc);
uwsgi_register_hook("wait_for_fs", uwsgi_hook_wait_for_fs);
uwsgi_register_hook("wait_for_file", uwsgi_hook_wait_for_file);
uwsgi_register_hook("wait_for_dir", uwsgi_hook_wait_for_dir);
uwsgi_register_hook("wait_for_socket", uwsgi_hook_wait_for_socket);
uwsgi_register_hook("unix_signal", uwsgi_hook_unix_signal);
// for testing
uwsgi_register_hook("exit", uwsgi_hook_exit);
uwsgi_register_hook("print", uwsgi_hook_print);
uwsgi_register_hook("log", uwsgi_hook_print);
}
int uwsgi_hooks_run_and_return(struct uwsgi_string_list *l, char *phase, char *context, int fatal) {
int final_ret = 0;
struct uwsgi_string_list *usl = NULL;
if (context) {
if (setenv("UWSGI_HOOK_CONTEXT", context, 1)) {
uwsgi_error("uwsgi_hooks_run_and_return()/setenv()");
return -1;
}
}
uwsgi_foreach(usl, l) {
char *colon = strchr(usl->value, ':');
if (!colon) {
uwsgi_log("invalid hook syntax, must be hook:args\n");
exit(1);
}
*colon = 0;
int private = 0;
char *action = usl->value;
// private hook ?
if (action[0] == '!') {
action++;
private = 1;
}
struct uwsgi_hook *uh = uwsgi_hook_by_name(action);
if (!uh) {
uwsgi_log("hook action not found: %s\n", action);
exit(1);
}
*colon = ':';
if (private) {
uwsgi_log("running --- PRIVATE HOOK --- (%s)...\n", phase);
}
else {
uwsgi_log("running \"%s\" (%s)...\n", usl->value, phase);
}
int ret = uh->func(colon+1);
if (ret != 0) {
if (fatal) {
if (context) {
unsetenv("UWSGI_HOOK_CONTEXT");
}
return ret;
}
final_ret = ret;
}
}
if (context) {
unsetenv("UWSGI_HOOK_CONTEXT");
}
return final_ret;
}
void uwsgi_hooks_run(struct uwsgi_string_list *l, char *phase, int fatal) {
int ret = uwsgi_hooks_run_and_return(l, phase, NULL, fatal);
if (fatal && ret != 0) {
uwsgi_log_verbose("FATAL hook failed, destroying instance\n");
if (uwsgi.master_process) {
if (uwsgi.workers) {
if (uwsgi.workers[0].pid == getpid()) {
kill_them_all(0);
return;
}
else {
if (kill(uwsgi.workers[0].pid, SIGINT)) {
uwsgi_error("uwsgi_hooks_run()/kill()");
exit(1);
}
return;
}
}
}
exit(1);
}
}
#if defined(__linux__) && !defined(OBSOLETE_LINUX_KERNEL)
/*
this is a special hook, allowing the Emperor to enter a vassal
namespace and call hooks in its namespace context.
*/
void uwsgi_hooks_setns_run(struct uwsgi_string_list *l, pid_t pid, uid_t uid, gid_t gid) {
int (*u_setns) (int, int) = (int (*)(int, int)) dlsym(RTLD_DEFAULT, "setns");
if (!u_setns) {
uwsgi_log("your system misses setns() syscall !!!\n");
return;
}
struct uwsgi_string_list *usl = NULL;
uwsgi_foreach(usl, l) {
// fist of all fork() the current process
pid_t new_pid = fork();
if (new_pid > 0) {
// wait for its death
int status;
if (waitpid(new_pid, &status, 0) < 0) {
uwsgi_error("uwsgi_hooks_setns_run()/waitpid()");
}
char *colon = strchr(usl->value, ':');
if (!colon) {
uwsgi_log("invalid hook syntax, must be hook:args\n");
exit(1);
}
else if (new_pid == 0) {
// from now on, freeing memory is useless
// now split args to know which namespaces to join
char *action = strchr(usl->value, ' ');
if (!action) {
uwsgi_log("invalid setns hook syntax, must be \"namespaces_list action:...\"\n");
exit(1);
}
char *pidstr = uwsgi_num2str(pid);
char *uidstr = uwsgi_num2str(uid);
char *gidstr = uwsgi_num2str(gid);
char *namespaces = uwsgi_concat2n(usl->value, action-usl->value, "", 0);
char *p, *ctx = NULL;
uwsgi_foreach_token(namespaces, ",", p, ctx) {
char *procfile = uwsgi_concat4("/proc/", pidstr, "/ns/", p);
int fd = open(procfile, O_RDONLY);
if (fd < 0) {
uwsgi_error_open(procfile);
exit(1);
}
if (u_setns(fd, 0) < 0){
uwsgi_error("uwsgi_hooks_setns_run()/setns()");
exit(1);
}
close(fd);
free(procfile);
}
if (setenv("UWSGI_VASSAL_PID", pidstr, 1)) {
uwsgi_error("uwsgi_hooks_setns_run()/setenv()");
exit(1);
}
if (setenv("UWSGI_VASSAL_UID", uidstr, 1)) {
uwsgi_error("uwsgi_hooks_setns_run()/setenv()");
exit(1);
}
if (setenv("UWSGI_VASSAL_GID", gidstr, 1)) {
uwsgi_error("uwsgi_hooks_setns_run()/setenv()");
exit(1);
}
// now run the action and then exit
*colon = 0;
int private = 0;
char *action = usl->value;
// private hook ?
if (action[0] == '!') {
action++;
char *colon = strchr(action, ':');
if (!colon) {
uwsgi_log("invalid hook syntax must be action:arg\n");
exit(1);
}
*colon = 0;
struct uwsgi_hook *uh = uwsgi_hook_by_name(action);
if (!uh) {
uwsgi_log("hook action not found: %s\n", action);
exit(1);
}
*colon = ':';
private = 1;
}
struct uwsgi_hook *uh = uwsgi_hook_by_name(action);
if (!uh) {
uwsgi_log("hook action not found: %s\n", action);
exit(1);
}
*colon = ':';
uwsgi_log("running \"%s\" (setns)...\n", usl->value);
exit(uh->func(colon+1));
if (private) {
uwsgi_log("running --- PRIVATE HOOK --- (%s)...\n", phase);
}
else {
uwsgi_error("uwsgi_hooks_setns_run()/fork()");
uwsgi_log("running \"%s\" (%s)...\n", usl->value, phase);
}
int ret = uh->func(colon+1);
if (fatal && ret != 0) {
uwsgi_log_verbose("FATAL hook failed, destroying instance\n");
if (uwsgi.master_process) {
if (uwsgi.workers) {
if (uwsgi.workers[0].pid == getpid()) {
kill_them_all(0);
return;
}
else {
if (kill(uwsgi.workers[0].pid, SIGINT)) {
uwsgi_error("uwsgi_hooks_run()/kill()");
exit(1);
}
return;
}
}
}
exit(1);
}
}
}
#endif
+4 -57
View File
@@ -9,7 +9,7 @@ extern struct uwsgi_server uwsgi;
static char *last_file = NULL;
static void ini_rstrip(char *line) {
void ini_rstrip(char *line) {
off_t i;
@@ -22,7 +22,7 @@ static void ini_rstrip(char *line) {
}
}
static char *ini_lstrip(char *line) {
char *ini_lstrip(char *line) {
off_t i;
char *ptr = line;
@@ -38,7 +38,7 @@ static char *ini_lstrip(char *line) {
return ptr;
}
static char *ini_get_key(char *key) {
char *ini_get_key(char *key) {
off_t i;
char *ptr = key;
@@ -54,7 +54,7 @@ static char *ini_get_key(char *key) {
return ptr;
}
static char *ini_get_line(char *ini, size_t size) {
char *ini_get_line(char *ini, size_t size) {
size_t i;
char *ptr = ini;
@@ -171,58 +171,5 @@ void uwsgi_ini_config(char *file, char *magic_table[]) {
colon[0] = ':';
}
}
void uwsgi_emperor_ini_attrs(char *filename, char *section_asked, struct uwsgi_dyn_dict **attrs) {
if (!section_asked) section_asked = "emperor";
char *ini = uwsgi_simple_file_read(filename);
if (!ini) return;
char *orig_ini = ini;
size_t len = strlen(ini);
char *section = "";
char *key, *val, *ini_line;
while (len) {
ini_line = ini_get_line(ini, len);
if (ini_line == NULL) {
break;
}
// skip empty line
key = ini_lstrip(ini);
ini_rstrip(key);
if (key[0] != 0) {
if (key[0] == '[') {
section = key + 1;
section[strlen(section) - 1] = 0;
}
else if (key[0] == ';' || key[0] == '#') {
// this is a comment
}
else {
// val is always valid, but (obviously) can be ignored
val = ini_get_key(key);
if (!strcmp(section, section_asked)) {
ini_rstrip(key);
struct uwsgi_string_list *usl = uwsgi_string_list_has_item(uwsgi.emperor_collect_attributes, key, strlen(key));
if (usl) {
val = ini_lstrip(val);
ini_rstrip(val);
char *value = uwsgi_str(val);
uwsgi_dyn_dict_new(attrs, usl->value, usl->len, value, strlen(value));
}
}
}
}
len -= (ini_line - ini);
ini += (ini_line - ini);
}
free(orig_ini);
}
+7 -51
View File
@@ -61,8 +61,6 @@ struct http_status_codes hsc[] = {
void uwsgi_init_default() {
uwsgi.cpus = 1;
uwsgi.new_argc = -1;
uwsgi.binary_argc = 1;
uwsgi.backtrace_depth = 64;
uwsgi.max_apps = 64;
@@ -107,12 +105,10 @@ void uwsgi_init_default() {
uwsgi.forkbomb_delay = 2;
uwsgi.async = 0;
uwsgi.async_warn_if_queue_full = 1;
uwsgi.async = 1;
uwsgi.listen_queue = 100;
uwsgi.cheaper_overload = 3;
uwsgi.cheaper_idle = 10;
uwsgi.log_master_bufsize = 8192;
@@ -256,42 +252,9 @@ void uwsgi_commandline_config() {
int i;
uwsgi.option_index = -1;
// required in case we want to call getopt_long from the beginning
optind = 0;
int argc = uwsgi.argc;
char **argv = uwsgi.argv;
// we might want to ignore some arguments not meant for us
char binary_argv0_pretty[256] = {'\0'};
char *binary_argv0_actual = NULL;
if (uwsgi.new_argc > -1 && uwsgi.new_argv) {
argc = uwsgi.new_argc;
argv = uwsgi.new_argv;
}
if (uwsgi.binary_argc > 1 && argc >= uwsgi.binary_argc) {
char *pretty = (char *)binary_argv0_pretty;
strncat(pretty, argv[0], 255);
for (i = 1; i < uwsgi.binary_argc; i++) {
if (strlen(pretty) + 1 + strlen(argv[i]) + 1 > 256)
break;
strcat(pretty, " ");
strcat(pretty, argv[i]);
}
argc -= uwsgi.binary_argc - 1;
argv += uwsgi.binary_argc - 1;
binary_argv0_actual = argv[0];
argv[0] = (char *)binary_argv0_pretty;
}
char *optname;
while ((i = getopt_long(argc, argv, uwsgi.short_options, uwsgi.long_options, &uwsgi.option_index)) != -1) {
while ((i = getopt_long(uwsgi.argc, uwsgi.argv, uwsgi.short_options, uwsgi.long_options, &uwsgi.option_index)) != -1) {
if (i == '?') {
uwsgi_log("getopt_long() error\n");
@@ -312,16 +275,14 @@ void uwsgi_commandline_config() {
add_exported_option(optname, optarg, 0);
}
if (binary_argv0_actual != NULL)
argv[0] = binary_argv0_actual;
#ifdef UWSGI_DEBUG
uwsgi_log("optind:%d argc:%d\n", optind, uwsgi.argc);
#endif
if (optind < argc) {
for (i = optind; i < argc; i++) {
char *lazy = argv[i];
if (optind < uwsgi.argc) {
for (i = optind; i < uwsgi.argc; i++) {
char *lazy = uwsgi.argv[i];
if (lazy[0] != '[') {
uwsgi_opt_load(NULL, lazy, NULL);
// manage magic mountpoint
@@ -438,8 +399,7 @@ pid_t uwsgi_daemonize2() {
uwsgi_write_pidfile(uwsgi.pidfile2);
}
if (uwsgi.log_master)
uwsgi_setup_log_master();
if (uwsgi.log_master) uwsgi_setup_log_master();
return uwsgi.mypid;
}
@@ -447,7 +407,7 @@ pid_t uwsgi_daemonize2() {
// fix/check related options
void sanitize_args() {
if (uwsgi.async > 0) {
if (uwsgi.async > 1) {
uwsgi.cores = uwsgi.async;
}
@@ -511,10 +471,6 @@ void sanitize_args() {
exit(1);
}
if (uwsgi.evil_reload_on_rss || uwsgi.evil_reload_on_as) {
if (!uwsgi.mem_collector_freq) uwsgi.mem_collector_freq = 3;
}
/* here we try to choose if thunder lock is a good thing */
#ifdef UNBIT
if (uwsgi.numproc > 1 && !uwsgi.map_socket) {
+43 -175
View File
@@ -90,7 +90,7 @@ char *uwsgi_simple_file_read(char *filename) {
}
if (fstat(fd, &sb)) {
uwsgi_error("uwsgi_simple_file_read()/fstat()");
uwsgi_error("fstat()");
close(fd);
goto end;
}
@@ -99,7 +99,7 @@ char *uwsgi_simple_file_read(char *filename) {
len = read(fd, buffer, sb.st_size);
if (len != sb.st_size) {
uwsgi_error("uwsgi_simple_file_read()/read()");
uwsgi_error("read()");
free(buffer);
close(fd);
goto end;
@@ -112,7 +112,7 @@ char *uwsgi_simple_file_read(char *filename) {
buffer[sb.st_size] = 0;
return buffer;
end:
return NULL;
return (char *) "";
}
@@ -277,7 +277,7 @@ static char *uwsgi_scheme_emperor(char *url, size_t *size, int add_zero) {
remains-=rlen;
}
remains = uh._pktsize;
remains = uh.pktsize;
if (!remains) {
uwsgi_log("[uwsgi-vassal] invalid config from %s\n", url);
exit(1);
@@ -300,7 +300,7 @@ static char *uwsgi_scheme_emperor(char *url, size_t *size, int add_zero) {
remains-=rlen;
}
*size = uh._pktsize + add_zero;
*size = uh.pktsize + add_zero;
return buffer;
}
@@ -342,10 +342,6 @@ static char *uwsgi_scheme_data(char *url, size_t *size, int add_zero) {
uwsgi_log("0 size binary data !!!\n");
exit(1);
}
if (datasize > SIZE_MAX) {
uwsgi_log("size binary data bigger than SIZE_MAX !!!\n");
exit(1);
}
fo = lseek(fd, -(datasize + 8), SEEK_CUR);
if (fo < 0) {
uwsgi_error("lseek()");
@@ -1067,7 +1063,7 @@ readok:
}
struct uwsgi_header *uh = (struct uwsgi_header *) buf;
uint16_t pktsize = uh->_pktsize;
uint16_t pktsize = uh->pktsize;
if (modifier1)
*modifier1 = uh->modifier1;
if (modifier2)
@@ -1123,48 +1119,46 @@ int uwsgi_proxy_nb(struct wsgi_request *wsgi_req, char *addr, struct uwsgi_buffe
struct uwsgi_buffer *headers = NULL;
if (!ub) {
int fd = uwsgi_connect(addr, 0, 1);
if (fd < 0) {
return -1;
}
}
int fd = uwsgi_connect(addr, 0, 1);
if (fd < 0) {
return -1;
}
int ret = uwsgi.wait_write_hook(fd, timeout);
if (ret <= 0) {
int ret = uwsgi.wait_write_hook(fd, timeout);
if (ret <= 0) {
goto end;
}
}
// send the request (+ remaining data)
if (uwsgi_write_true_nb(fd, ub->buf, ub->pos, timeout)) {
goto end;
}
// send the body
while(remains > 0) {
ssize_t rlen = 0;
char *buf = uwsgi_request_body_read(wsgi_req, 8192, &rlen);
if (!buf) {
// send the request (+ remaining data)
if (ub) {
if (uwsgi_write_true_nb(fd, ub->buf, ub->pos, timeout)) {
goto end;
}
if (buf == uwsgi.empty) break;
// write data to the node
if (uwsgi_write_true_nb(fd, buf, rlen, timeout)) {
goto end;
}
remains -= rlen;
}
}
// read the response
// send the body
while(remains > 0) {
ssize_t rlen = 0;
char *buf = uwsgi_request_body_read(wsgi_req, 8192, &rlen);
if (!buf) {
goto end;
}
if (buf == uwsgi.empty) break;
// write data to the node
if (uwsgi_write_true_nb(fd, buf, rlen, timeout)) {
goto end;
}
remains -= rlen;
}
// read the response
headers = uwsgi_buffer_new(8192);
// max 64k headers
ub->limit = UMAX16;
for(;;) {
char buf[8192];
ssize_t rlen = uwsgi_read_true_nb(fd, buf, 8192, timeout);
if (rlen > 0) {
for(;;) {
char buf[8192];
ssize_t rlen = uwsgi_read_true_nb(fd, buf, 8192, timeout);
if (rlen > 0) {
if (headers) {
if (uwsgi_buffer_append(headers, buf, rlen)) {
goto end;
@@ -1178,14 +1172,14 @@ int uwsgi_proxy_nb(struct wsgi_request *wsgi_req, char *addr, struct uwsgi_buffe
}
}
else {
if (uwsgi_response_write_body_do(wsgi_req, buf, rlen)) {
break;
}
if (uwsgi_response_write_body_do(wsgi_req, buf, rlen)) {
break;
}
}
continue;
}
break;
}
continue;
}
break;
}
if (headers) uwsgi_buffer_destroy(headers);
close(fd);
@@ -1508,129 +1502,3 @@ clear:
#endif
}
ssize_t uwsgi_recv_cred_and_fds(int fd, char *buf, size_t buf_len, pid_t *pid, uid_t *uid, gid_t *gid, int *fds, int *fds_count) {
#if defined(SCM_CREDENTIALS) && defined(SCM_RIGHTS)
ssize_t ret = -1;
size_t msg_len = CMSG_SPACE(sizeof(struct ucred)) + CMSG_SPACE(sizeof(int) * (*fds_count));
// allocate space for credentials and file descriptors
void *msg_control = uwsgi_calloc(msg_len);
// read into buf
struct iovec iov;
iov.iov_base = buf;
iov.iov_len = buf_len;
struct msghdr msg;
memset(&msg, 0, sizeof(msg));
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
// set cmsg
msg.msg_control = msg_control;
msg.msg_controllen = msg_len;
ssize_t len = recvmsg(fd, &msg, 0);
if (len <= 0) {
uwsgi_error("uwsgi_recv_cred_and_fds()/recvmsg()");
goto clear;
}
// reset the number of fds
*fds_count = 0;
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
while(cmsg) {
if (cmsg->cmsg_level != SOL_SOCKET) goto next;
if (cmsg->cmsg_type == SCM_RIGHTS) {
size_t fds_len = cmsg->cmsg_len - ((char *) CMSG_DATA(cmsg) - (char *) cmsg);
memcpy(fds, CMSG_DATA(cmsg), fds_len);
*fds_count = fds_len/sizeof(int);
}
else if (cmsg->cmsg_type == SCM_CREDENTIALS) {
struct ucred *u = (struct ucred *) CMSG_DATA(cmsg);
*pid = u->pid;
*uid = u->uid;
*gid = u->gid;
}
next:
cmsg=CMSG_NXTHDR(&msg,cmsg);
}
ret = len;
clear:
free(msg_control);
return ret;
#else
return -1;
#endif
}
int uwsgi_send_fds_and_body(int fd, int *fds, int fds_count, char *body, size_t len) {
int ret = -1;
struct msghdr msg;
void *msg_control = uwsgi_malloc(CMSG_SPACE(sizeof(int) * fds_count));
struct iovec iov;
struct cmsghdr *cmsg;
iov.iov_base = body;
iov.iov_len = len;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_flags = 0;
msg.msg_control = msg_control;
msg.msg_controllen = CMSG_SPACE(sizeof(int) * fds_count);
cmsg = CMSG_FIRSTHDR(&msg);
cmsg->cmsg_len = CMSG_LEN(sizeof(int) * fds_count);
cmsg->cmsg_level = SOL_SOCKET;
cmsg->cmsg_type = SCM_RIGHTS;
unsigned char *fd_ptr = CMSG_DATA(cmsg);
memcpy(fd_ptr, fds, sizeof(int) * fds_count);
ssize_t rlen = sendmsg(fd, &msg, 0);
if (rlen <= 0) {
uwsgi_error("uwsgi_send_fds_and_body()/sendmsg()");
goto end;
}
else {
size_t remains = len - rlen;
while(remains > 0) {
char *buf = body + rlen;
ssize_t wlen = write(fd, buf, remains);
if (wlen == 0) goto end;
if (wlen < 0) {
if (uwsgi_is_again()) {
// wait for write
continue;
}
uwsgi_error("uwsgi_send_fds_and_body()/write()");
goto end;
}
rlen += wlen;
remains -= wlen;
}
}
ret = 0;
end:
free(msg_control);
return ret;
}
+9 -7
View File
@@ -277,12 +277,14 @@ static void legions_check_nodes_step2() {
memcpy(best_uuid, node->uuid, 36);
}
// go on if i am not an arbiter
// no potential Lord is available, i will propose myself
// but only if i am not suspended...
else if (ul->valor > 0 && uwsgi_now() > ul->suspended_til) {
best_valor = ul->valor;
memcpy(best_uuid, ul->uuid, 36);
i_am_the_best = 1;
else if (ul->valor > 0) {
// no potential Lord is available, i will propose myself
// but only if i am not suspended...
if (uwsgi_now() > ul->suspended_til) {
best_valor = ul->valor;
memcpy(best_uuid, ul->uuid, 36);
i_am_the_best = 1;
}
}
else {
// empty lord
@@ -570,7 +572,7 @@ static void *legion_loop(void *foobar) {
d_len += d2_len;
if (d_len != uh->_pktsize) {
if (d_len != uh->pktsize) {
uwsgi_log("[uwsgi-legion] invalid packet size\n");
continue;
}
+6 -20
View File
@@ -94,12 +94,12 @@ retry:
#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_setprotocol(&attr, PTHREAD_PRIO_INHERIT)) {
uwsgi_log("unable to set PTHREAD_PRIO_INHERIT\n");
exit(1);
}
if (pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST)) {
if (pthread_mutexattr_setrobust_np(&attr, PTHREAD_MUTEX_ROBUST)) {
uwsgi_log("unable to make the mutex 'robust'\n");
exit(1);
}
@@ -161,7 +161,7 @@ void uwsgi_lock_fast(struct uwsgi_lock_item *uli) {
#ifdef EOWNERDEAD
if (pthread_mutex_lock((pthread_mutex_t *) uli->lock_ptr) == EOWNERDEAD) {
uwsgi_log("[deadlock-detector] a process holding a robust mutex died. recovering...\n");
pthread_mutex_consistent((pthread_mutex_t *) uli->lock_ptr);
pthread_mutex_consistent_np((pthread_mutex_t *) uli->lock_ptr);
}
#else
pthread_mutex_lock((pthread_mutex_t *) uli->lock_ptr);
@@ -476,20 +476,6 @@ void uwsgi_rwunlock_fast(struct uwsgi_lock_item *uli) {
#endif
#ifdef __RUMP__
int semctl(int _0, int _1, int _2, ...) {
return 0;
}
int semget(key_t _0, int _1, int _2) {
return 0;
}
int semop(int _0, struct sembuf * _1, size_t _2) {
return 0;
}
#undef UWSGI_LOCK_ENGINE_NAME
#define UWSGI_LOCK_ENGINE_NAME "fake"
#endif
struct uwsgi_lock_item *uwsgi_lock_ipcsem_init(char *id) {
// used by ftok
+10 -22
View File
@@ -3,7 +3,6 @@
#endif
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__OpenBSD__)
#include <sys/user.h>
#include <sys/sysctl.h>
#include <kvm.h>
#elif defined(__sun__)
/* Terrible Hack !!! */
@@ -14,6 +13,10 @@
#define _FILE_OFFSET_BITS 64
#endif
#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__)
#include <sys/sysctl.h>
#endif
#ifdef __DragonFly__
#include <uwsgi.h>
#endif
@@ -291,8 +294,8 @@ void logto(char *logfile) {
uwsgi.logfile = logfile;
if (uwsgi.chmod_logfile_value) {
if (fchmod(fd, uwsgi.chmod_logfile_value)) {
uwsgi_error("fchmod()");
if (chmod(uwsgi.logfile, uwsgi.chmod_logfile_value)) {
uwsgi_error("chmod()");
}
}
}
@@ -712,12 +715,12 @@ void uwsgi_logit_simple(struct wsgi_request *wsgi_req) {
}
rlen = snprintf(logpkt, 4096, "[pid: %d|app: %d|req: %d/%llu] %.*s (%.*s) {%d vars in %llu bytes} [%.*s] %.*s %.*s => generated %llu bytes in %llu %s%s(%.*s %d) %d headers in %llu bytes (%d switches on core %d)\n", (int) uwsgi.mypid, wsgi_req->app_id, app_req, (unsigned long long) uwsgi.workers[0].requests, wsgi_req->remote_addr_len, wsgi_req->remote_addr, wsgi_req->remote_user_len, wsgi_req->remote_user, wsgi_req->var_cnt, (unsigned long long) wsgi_req->len,
rlen = snprintf(logpkt, 4096, "[pid: %d|app: %d|req: %d/%llu] %.*s (%.*s) {%d vars in %d bytes} [%.*s] %.*s %.*s => generated %llu bytes in %llu %s%s(%.*s %d) %d headers in %llu bytes (%d switches on core %d)\n", (int) uwsgi.mypid, wsgi_req->app_id, app_req, (unsigned long long) uwsgi.workers[0].requests, wsgi_req->remote_addr_len, wsgi_req->remote_addr, wsgi_req->remote_user_len, wsgi_req->remote_user, wsgi_req->var_cnt, wsgi_req->uh->pktsize,
24, time_request, wsgi_req->method_len, wsgi_req->method, wsgi_req->uri_len, wsgi_req->uri, (unsigned long long) wsgi_req->response_size, (unsigned long long) rt, tsize, via, wsgi_req->protocol_len, wsgi_req->protocol, wsgi_req->status, wsgi_req->header_cnt, (unsigned long long) wsgi_req->headers_size, wsgi_req->switches, wsgi_req->async_id);
// not enough space for logging the request, just log a (safe) minimal message
if (rlen > 4096) {
rlen = snprintf(logpkt, 4096, "[pid: %d|app: %d|req: %d/%llu] 0.0.0.0 () {%d vars in %llu bytes} [%.*s] - - => generated %llu bytes in %llu %s%s(- %d) %d headers in %llu bytes (%d switches on core %d)\n", (int) uwsgi.mypid, wsgi_req->app_id, app_req, (unsigned long long) uwsgi.workers[0].requests, wsgi_req->var_cnt, (unsigned long long) wsgi_req->len,
rlen = snprintf(logpkt, 4096, "[pid: %d|app: %d|req: %d/%llu] 0.0.0.0 () {%d vars in %d bytes} [%.*s] - - => generated %llu bytes in %llu %s%s(- %d) %d headers in %llu bytes (%d switches on core %d)\n", (int) uwsgi.mypid, wsgi_req->app_id, app_req, (unsigned long long) uwsgi.workers[0].requests, wsgi_req->var_cnt, wsgi_req->uh->pktsize,
24, time_request, (unsigned long long) wsgi_req->response_size, (unsigned long long) rt, tsize, via, wsgi_req->status, wsgi_req->header_cnt, (unsigned long long) wsgi_req->headers_size, wsgi_req->switches, wsgi_req->async_id);
// argh, last resort, truncate it
if (rlen > 4096) {
@@ -748,11 +751,10 @@ void get_memusage(uint64_t * rss, uint64_t * vsz) {
i = fscanf(procfile, "%*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %*s %llu %lld", (unsigned long long *) vsz, (unsigned long long *) rss);
if (i != 2) {
uwsgi_log("warning: invalid record in /proc/self/stat\n");
} else {
*rss = *rss * uwsgi.page_size;
}
fclose(procfile);
}
*rss = *rss * uwsgi.page_size;
#elif defined(__CYGWIN__)
// same as Linux but rss is not in pages...
FILE *procfile;
@@ -1213,7 +1215,7 @@ static ssize_t uwsgi_lf_rssM(struct wsgi_request * wsgi_req, char **buf) {
}
static ssize_t uwsgi_lf_pktsize(struct wsgi_request * wsgi_req, char **buf) {
*buf = uwsgi_num2str(wsgi_req->len);
*buf = uwsgi_num2str(wsgi_req->uh->pktsize);
return strlen(*buf);
}
@@ -1512,7 +1514,6 @@ static void *logger_thread_loop(void *noarg) {
if (uwsgi.req_log_master) {
logpoll[1].events = POLLIN;
logpoll[1].fd = uwsgi.shared->worker_req_log_pipe[0];
logpolls++;
}
@@ -1552,19 +1553,6 @@ void uwsgi_threaded_logger_spawn() {
}
}
void uwsgi_threaded_logger_worker_spawn() {
pthread_t logger_thread;
pthread_mutex_init(&uwsgi.threaded_logger_lock, NULL);
uwsgi.log_master_buf = uwsgi_malloc(uwsgi.log_master_bufsize);
if (pthread_create(&logger_thread, NULL, logger_thread_loop, NULL)) {
uwsgi_error_safe("uwsgi_threaded_logger_worker_spawn()/pthread_create()");
exit(1);
}
}
void uwsgi_register_log_encoder(char *name, char *(*func)(struct uwsgi_log_encoder *, char *, size_t, size_t *)) {
struct uwsgi_log_encoder *old_ule = NULL, *ule = uwsgi.log_encoders;
+17 -52
View File
@@ -2,33 +2,6 @@
extern struct uwsgi_server uwsgi;
static void master_check_processes() {
// run the function, only if required
if (!uwsgi.die_on_no_workers) return;
int alive_processes = 0;
int dead_processes = 0;
int i;
for (i = 1; i <= uwsgi.numproc; i++) {
if (uwsgi.workers[i].cheaped == 0 && uwsgi.workers[i].pid > 0) {
alive_processes++;
}
else {
dead_processes++;
}
}
if (uwsgi.die_on_no_workers) {
if (!alive_processes) {
uwsgi_log_verbose("no more processes running, auto-killing ...\n");
exit(1);
// never here;
}
}
}
void uwsgi_update_load_counters() {
int i;
@@ -285,18 +258,17 @@ static void master_check_listen_queue() {
if (uwsgi_sock->queue > backlog) {
backlog = uwsgi_sock->queue;
}
if (uwsgi_sock->queue > 0 && uwsgi_sock->queue >= uwsgi_sock->max_queue) {
uwsgi_log_verbose("*** uWSGI listen queue of socket \"%s\" (fd: %d) full !!! (%llu/%llu) ***\n", uwsgi_sock->name, uwsgi_sock->fd, (unsigned long long) uwsgi_sock->queue, (unsigned long long) uwsgi_sock->max_queue);
}
if (uwsgi.alarm_backlog) {
char buf[1024];
int ret = snprintf(buf, 1024, "listen queue of socket \"%s\" (fd: %d) full !!! (%llu/%llu)", uwsgi_sock->name, uwsgi_sock->fd, (unsigned long long) uwsgi_sock->queue, (unsigned long long) uwsgi_sock->max_queue);
if (ret > 0 && ret < 1024) {
struct uwsgi_string_list *usl = NULL;
uwsgi_foreach(usl, uwsgi.alarm_backlog) {
uwsgi_alarm_trigger(usl->value, buf, ret);
}
if (uwsgi.alarm_backlog) {
char buf[1024];
int ret = snprintf(buf, 1024, "listen queue of socket \"%s\" (fd: %d) full !!! (%llu/%llu)", uwsgi_sock->name, uwsgi_sock->fd, (unsigned long long) uwsgi_sock->queue, (unsigned long long) uwsgi_sock->max_queue);
if (ret > 0 && ret < 1024) {
struct uwsgi_string_list *usl = NULL;
uwsgi_foreach(usl, uwsgi.alarm_backlog) {
uwsgi_alarm_trigger(usl->value, buf, ret);
}
}
}
@@ -361,10 +333,14 @@ int master_loop(char **argv, char **environ) {
uwsgi_unix_signal(SIGTSTP, suspend_resume_them_all);
uwsgi_unix_signal(SIGHUP, grace_them_all);
uwsgi_unix_signal(SIGTERM, kill_them_all);
uwsgi_unix_signal(SIGQUIT, reap_them_all);
if (uwsgi.die_on_term) {
uwsgi_unix_signal(SIGTERM, kill_them_all);
uwsgi_unix_signal(SIGQUIT, reap_them_all);
}
else {
uwsgi_unix_signal(SIGTERM, reap_them_all);
uwsgi_unix_signal(SIGQUIT, kill_them_all);
}
uwsgi_unix_signal(SIGINT, kill_them_all);
uwsgi_unix_signal(SIGUSR1, stats);
@@ -670,13 +646,6 @@ int master_loop(char **argv, char **environ) {
return 0;
}
// spooler cheap management
if (uwsgi.spooler_cheap) {
if ((uwsgi.master_cycles % uwsgi.spooler_frequency) == 0) {
uwsgi_spooler_cheap_check();
}
}
// check if someone is dead
diedpid = waitpid(WAIT_ANY, &waitpid_status, WNOHANG);
@@ -762,8 +731,6 @@ int master_loop(char **argv, char **environ) {
// update load counter
uwsgi_update_load_counters();
master_check_processes();
// check uwsgi-cron table
if (ushared->cron_cnt) {
@@ -1000,9 +967,7 @@ next:
// ok a worker died...
uwsgi.workers[thewid].pid = 0;
// only to be safe :P
for(i=0;i<uwsgi.cores;i++) {
uwsgi.workers[thewid].cores[i].harakiri = 0;
}
uwsgi.workers[thewid].harakiri = 0;
// ok, if we are reloading or dying, just continue the master loop
// as soon as all of the workers have pid == 0, the action (exit, or reload) is triggered
+16 -34
View File
@@ -39,8 +39,6 @@ int uwsgi_master_check_reload(char **argv) {
// check for chain reload
void uwsgi_master_check_chain() {
static time_t last_check = 0;
if (!uwsgi.status.chain_reloading) return;
// we need to ensure the previous worker (if alive) is accepting new requests
@@ -51,11 +49,7 @@ void uwsgi_master_check_chain() {
if (previous_worker->pid > 0 && !previous_worker->cheaped) {
// the worker has been respawned but it is still not ready
if (previous_worker->accepting == 0) {
time_t now = uwsgi_now();
if (now != last_check) {
uwsgi_log_verbose("chain is still waiting for worker %d...\n", uwsgi.status.chain_reloading-1);
last_check = now;
}
uwsgi_log_verbose("chain is still waiting for worker %d...\n", uwsgi.status.chain_reloading-1);
return;
}
}
@@ -176,27 +170,21 @@ done:
}
int uwsgi_master_check_workers_deadline() {
int i,j;
int i;
int ret = 0;
for (i = 1; i <= uwsgi.numproc; i++) {
for(j=0;j<uwsgi.cores;j++) {
/* first check for harakiri */
if (uwsgi.workers[i].cores[j].harakiri > 0) {
if (uwsgi.workers[i].cores[j].harakiri < (time_t) uwsgi.current_time) {
uwsgi_log_verbose("HARAKIRI triggered by worker %d core %d !!!\n", i, j);
trigger_harakiri(i);
ret = 1;
break;
}
/* first check for harakiri */
if (uwsgi.workers[i].harakiri > 0) {
if (uwsgi.workers[i].harakiri < (time_t) uwsgi.current_time) {
trigger_harakiri(i);
ret = 1;
}
/* then user-defined harakiri */
if (uwsgi.workers[i].cores[j].user_harakiri > 0) {
uwsgi_log_verbose("HARAKIRI (user) triggered by worker %d core %d !!!\n", i, j);
if (uwsgi.workers[i].cores[j].user_harakiri < (time_t) uwsgi.current_time) {
trigger_harakiri(i);
ret = 1;
break;
}
}
/* then user-defined harakiri */
if (uwsgi.workers[i].user_harakiri > 0) {
if (uwsgi.workers[i].user_harakiri < (time_t) uwsgi.current_time) {
trigger_harakiri(i);
ret = 1;
}
}
// then for evil memory checkers
@@ -308,15 +296,9 @@ int uwsgi_master_check_spoolers_death(int diedpid) {
struct uwsgi_spooler *uspool = uwsgi.spoolers;
while (uspool) {
if (uspool->pid > 0 && diedpid == uspool->pid) {
if (uwsgi.spooler_cheap) {
uwsgi_log_verbose("spooler %s ended\n", uspool->dir);
uspool->pid = 0;
}
else {
uwsgi_log("OOOPS the spooler is no more...trying respawn...\n");
uspool->respawned++;
uspool->pid = spooler_start(uspool);
}
uwsgi_log("OOOPS the spooler is no more...trying respawn...\n");
uspool->respawned++;
uspool->pid = spooler_start(uspool);
return -1;
}
uspool = uspool->next;
+11 -4
View File
@@ -45,7 +45,7 @@ int uwsgi_master_manage_events(int interesting_fd) {
// emperor event ?
if (uwsgi.has_emperor) {
if (uwsgi.emperor_fd_proxy > -1 && interesting_fd == uwsgi.emperor_fd_proxy) {
uwsgi_master_manage_emperor_proxy(uwsgi.emperor_fd_proxy, uwsgi.emperor_fd, uwsgi.emperor_fd_config, -1);
uwsgi_master_manage_emperor_proxy();
return 0;
}
@@ -118,9 +118,16 @@ int uwsgi_master_manage_events(int interesting_fd) {
else {
uwsgi_log_verbose("*** fd %d ready !!! ***\n", interesting_fd);
}
uwsgi_block_signal(SIGQUIT);
reap_them_all(0);
uwsgi_unblock_signal(SIGQUIT);
if (uwsgi.die_on_term) {
uwsgi_block_signal(SIGQUIT);
reap_them_all(0);
uwsgi_unblock_signal(SIGQUIT);
}
else {
uwsgi_block_signal(SIGTERM);
reap_them_all(0);
uwsgi_unblock_signal(SIGTERM);
}
if (usl->custom2 > 8) free(tmp);
return 0;
}
+7 -82
View File
@@ -221,7 +221,7 @@ int uwsgi_cheaper_algo_manual(int can_spawn) {
-- Cheaper, spare algorithm, adapted from old-fashioned spare system --
when all of the workers are busy, the overload_count is incremented.
as soon as overload_count reaches to uwsgi.cheaper_overload (--cheaper-overload options)
as soon as overload_count is higher than uwsgi.cheaper_overload (--cheaper-overload options)
at most cheaper_step (default to 1) new workers are spawned.
when at least one worker is free, the overload_count is decremented and the idle_count is incremented.
@@ -275,7 +275,7 @@ int uwsgi_cheaper_algo_spare(int can_spawn) {
healthy:
// are we overloaded ?
if (can_spawn && overload_count >= uwsgi.cheaper_overload) {
if (can_spawn && overload_count > uwsgi.cheaper_overload) {
#ifdef UWSGI_DEBUG
uwsgi_log("overloaded !!!\n");
@@ -333,72 +333,6 @@ healthy:
}
/*
-- Cheaper, spare2 algorithm, for large workload --
This algorithm is very similar to spare, but more suited for higher workload.
This algorithm increase workers *before* overloaded, and decrease workers slowly.
This algorithm uses these options: chaper, cheaper-initial, cheaper-step and cheaper-idle.
* When number of idle workers is smaller than cheaper count, increase
min(cheaper-step, cheaper - idle workers) workers.
* When number of idle workers is larger than cheaper count, increase idle_count.
* When idle_count >= cheaper-idle, decrease worker.
*/
int uwsgi_cheaper_algo_spare2(int can_spawn) {
static int idle_count = 0;
int i, idle_workers, busy_workers, cheaped_workers;
// count the number of idle and busy workers
idle_workers = busy_workers = 0;
for (i = 1; i <= uwsgi.numproc; i++) {
if (uwsgi.workers[i].cheaped == 0 && uwsgi.workers[i].pid > 0) {
if (uwsgi_worker_is_busy(i) == 1) {
busy_workers++;
} else {
idle_workers++;
}
}
}
cheaped_workers = uwsgi.numproc - (idle_workers + busy_workers);
#ifdef UWSGI_DEBUG
uwsgi_log("cheaper-spare2: idle=%d, busy=%d, cheaped=%d, idle_count=%d\n",
idle_workers, busy_workers, cheaped_workers, idle_count);
#endif
// should we increase workers?
if (idle_workers < uwsgi.cheaper_count) {
int spawn;
idle_count = 0;
if (!can_spawn)
return 0;
spawn = uwsgi.cheaper_count - idle_workers;
if (spawn > cheaped_workers)
spawn = cheaped_workers;
if (spawn > uwsgi.cheaper_step)
spawn = uwsgi.cheaper_step;
return spawn;
}
if (idle_workers == uwsgi.cheaper_count) {
idle_count = 0;
return 0;
}
// decrease workers
idle_count++;
if (idle_count < uwsgi.cheaper_idle)
return 0;
idle_count = 0;
return -1;
}
/*
@@ -456,8 +390,6 @@ void uwsgi_reload(char **argv) {
int i;
int waitpid_status;
if (uwsgi.new_argv) argv = uwsgi.new_argv;
if (!uwsgi.master_is_reforked) {
// call a series of waitpid to ensure all processes (gateways, mules and daemons) are dead
@@ -700,7 +632,7 @@ void uwsgi_fixup_fds(int wid, int muleid, struct uwsgi_gateway *ug) {
}
int uwsgi_respawn_worker(int wid) {
int i;
int respawns = uwsgi.workers[wid].respawn_count;
// the workers is not accepting (obviously)
uwsgi.workers[wid].accepting = 0;
@@ -709,10 +641,8 @@ int uwsgi_respawn_worker(int wid) {
// ... same for update time
uwsgi.workers[wid].last_spawn = uwsgi.current_time;
// ... and memory/harakiri
for(i=0;i<uwsgi.cores;i++) {
uwsgi.workers[wid].cores[i].harakiri = 0;
uwsgi.workers[wid].cores[i].user_harakiri = 0;
}
uwsgi.workers[wid].harakiri = 0;
uwsgi.workers[wid].user_harakiri = 0;
uwsgi.workers[wid].pending_harakiri = 0;
uwsgi.workers[wid].rss_size = 0;
uwsgi.workers[wid].vsz_size = 0;
@@ -730,6 +660,8 @@ int uwsgi_respawn_worker(int wid) {
// this is required for various checks
uwsgi.workers[wid].delta_requests = 0;
int i;
if (uwsgi.threaded_logger) {
pthread_mutex_lock(&uwsgi.threaded_logger_lock);
}
@@ -772,7 +704,6 @@ int uwsgi_respawn_worker(int wid) {
for(i=0;i<uwsgi.cores;i++) {
uwsgi.workers[uwsgi.mywid].cores[i].in_request = 0;
memset(&uwsgi.workers[uwsgi.mywid].cores[i].req, 0, sizeof(struct wsgi_request));
memset(uwsgi.workers[uwsgi.mywid].cores[i].buffer, 0, sizeof(struct uwsgi_header));
}
uwsgi_fixup_fds(wid, 0, NULL);
@@ -789,10 +720,6 @@ int uwsgi_respawn_worker(int wid) {
}
}
if (uwsgi.threaded_logger) {
pthread_mutex_unlock(&uwsgi.threaded_logger_lock);
}
return 1;
}
else if (pid < 1) {
@@ -1936,5 +1863,3 @@ void uwsgi_dump_worker(int wid, char *msg) {
}
uwsgi_log_verbose("%s !!! end of worker %d status !!!\n",msg, wid);
}
/* vim: set ts=8 sts=0 sw=0 noexpandtab : */
+2 -2
View File
@@ -198,7 +198,7 @@ void uwsgi_mule_handler() {
#ifdef UWSGI_DEBUG
uwsgi_log_verbose("master sent signal %d to mule %d\n", uwsgi_signal, uwsgi.muleid);
#endif
if (uwsgi_signal_handler(NULL, uwsgi_signal)) {
if (uwsgi_signal_handler(uwsgi_signal)) {
uwsgi_log_verbose("error managing signal %d on mule %d\n", uwsgi_signal, uwsgi.muleid);
}
}
@@ -362,7 +362,7 @@ retry:
#ifdef UWSGI_DEBUG
uwsgi_log_verbose("master sent signal %d to mule %d\n", uwsgi_signal, uwsgi.muleid);
#endif
if (uwsgi_signal_handler(NULL, uwsgi_signal)) {
if (uwsgi_signal_handler(uwsgi_signal)) {
uwsgi_log_verbose("error managing signal %d on mule %d\n", uwsgi_signal, uwsgi.muleid);
}
// set the error condition
-3
View File
@@ -613,9 +613,6 @@ int uwsgi_offload_run(struct wsgi_request *wsgi_req, struct uwsgi_offload_reques
if (uor->takeover) {
wsgi_req->fd_closed = 1;
// avoid edge-triggered mode
if (wsgi_req->socket->retry)
wsgi_req->socket->retry[wsgi_req->async_id] = 0;
}
if (uwsgi_offload_enqueue(wsgi_req, uor)) {
+11 -11
View File
@@ -46,10 +46,10 @@ int uwsgi_read_response(int fd, struct uwsgi_header *uh, int timeout, char **buf
break;
}
if (buf && uh->_pktsize > 0) {
if (buf && uh->pktsize > 0) {
if (*buf == NULL)
*buf = uwsgi_malloc(uh->_pktsize);
remains = uh->_pktsize;
*buf = uwsgi_malloc(uh->pktsize);
remains = uh->pktsize;
ptr = *buf;
ret = -1;
while (remains > 0) {
@@ -578,7 +578,7 @@ int uwsgi_parse_vars(struct wsgi_request *wsgi_req) {
struct uwsgi_dyn_dict *udd;
ptrbuf = buffer;
bufferend = ptrbuf + wsgi_req->len;
bufferend = ptrbuf + wsgi_req->uh->pktsize;
int i;
/* set an HTTP 500 status as default */
@@ -715,7 +715,7 @@ next:
}
if (uwsgi.manage_script_name) {
if (uwsgi_apps_cnt > 0 && wsgi_req->path_info_len >= 1 && wsgi_req->path_info_pos != -1) {
if (uwsgi_apps_cnt > 0 && wsgi_req->path_info_len > 1 && wsgi_req->path_info_pos != -1) {
// starts with 1 as the 0 app is the default (/) one
int best_found = 0;
char *orig_path_info = wsgi_req->path_info;
@@ -1050,7 +1050,7 @@ char *uwsgi_req_append(struct wsgi_request *wsgi_req, char *key, uint16_t keylen
}
}
if ((wsgi_req->len + (2 + keylen + 2 + vallen)) > uwsgi.buffer_size) {
if ((wsgi_req->uh->pktsize + (2 + keylen + 2 + vallen)) > uwsgi.buffer_size) {
uwsgi_log("not enough buffer space to add %.*s variable, consider increasing it with the --buffer-size option\n", keylen, key);
return NULL;
}
@@ -1060,7 +1060,7 @@ char *uwsgi_req_append(struct wsgi_request *wsgi_req, char *key, uint16_t keylen
return NULL;
}
char *ptr = wsgi_req->buffer + wsgi_req->len;
char *ptr = wsgi_req->buffer + wsgi_req->uh->pktsize;
*ptr++ = (uint8_t) (keylen & 0xff);
*ptr++ = (uint8_t) ((keylen >> 8) & 0xff);
@@ -1081,7 +1081,7 @@ char *uwsgi_req_append(struct wsgi_request *wsgi_req, char *key, uint16_t keylen
wsgi_req->hvec[wsgi_req->var_cnt].iov_len = vallen;
wsgi_req->var_cnt++;
wsgi_req->len += (2 + keylen + 2 + vallen);
wsgi_req->uh->pktsize += (2 + keylen + 2 + vallen);
return ptr;
}
@@ -1106,7 +1106,7 @@ int uwsgi_req_append_path_info_with_index(struct wsgi_request *wsgi_req, char *i
wsgi_req->path_info_len += need_slash + index_len;
// 2 + 9 + 2
if ((wsgi_req->len + (13 + wsgi_req->path_info_len)) > uwsgi.buffer_size) {
if ((wsgi_req->uh->pktsize + (13 + wsgi_req->path_info_len)) > uwsgi.buffer_size) {
uwsgi_log("not enough buffer space to transform the PATH_INFO variable, consider increasing it with the --buffer-size option\n");
return -1;
}
@@ -1117,7 +1117,7 @@ int uwsgi_req_append_path_info_with_index(struct wsgi_request *wsgi_req, char *i
}
uint16_t keylen = 9;
char *ptr = wsgi_req->buffer + wsgi_req->len;
char *ptr = wsgi_req->buffer + wsgi_req->uh->pktsize;
*ptr++ = (uint8_t) (keylen & 0xff);
*ptr++ = (uint8_t) ((keylen >> 8) & 0xff);
@@ -1143,7 +1143,7 @@ int uwsgi_req_append_path_info_with_index(struct wsgi_request *wsgi_req, char *i
wsgi_req->hvec[wsgi_req->var_cnt].iov_len = wsgi_req->path_info_len;
wsgi_req->var_cnt++;
wsgi_req->len += 13 + wsgi_req->path_info_len;
wsgi_req->uh->pktsize += 13 + wsgi_req->path_info_len;
wsgi_req->path_info = new_path_info;
return 0;
+2 -2
View File
@@ -477,7 +477,7 @@ int uwsgi_postbuffer_do_in_mem(struct wsgi_request *wsgi_req) {
while (remains > 0) {
if (uwsgi.harakiri_options.workers > 0) {
inc_harakiri(wsgi_req, uwsgi.harakiri_options.workers);
inc_harakiri(uwsgi.harakiri_options.workers);
}
ssize_t rlen = wsgi_req->socket->proto_read_body(wsgi_req, ptr, remains);
@@ -551,7 +551,7 @@ int uwsgi_postbuffer_do_in_disk(struct wsgi_request *wsgi_req) {
// during post buffering we need to constantly reset the harakiri
if (uwsgi.harakiri_options.workers > 0) {
inc_harakiri(wsgi_req, uwsgi.harakiri_options.workers);
inc_harakiri(uwsgi.harakiri_options.workers);
}
// we use the already available post buffering buffer to read chunks....
+2 -84
View File
@@ -493,7 +493,7 @@ done:
r = r->next;
}
uwsgi_log("unable to register route \"%s\". Missing router for: \"%s\"\n", value, command);
uwsgi_log("unable to register route \"%s\"\n", value);
exit(1);
}
@@ -702,7 +702,7 @@ static int uwsgi_router_simple_math_divide(struct uwsgi_route *ur, char *arg) {
// harakiri router
static int uwsgi_router_harakiri_func(struct wsgi_request *wsgi_req, struct uwsgi_route *route) {
if (route->custom > 0) {
set_user_harakiri(wsgi_req, route->custom);
set_user_harakiri(route->custom);
}
return UWSGI_ROUTE_NEXT;
}
@@ -756,27 +756,6 @@ static int uwsgi_router_fixcl(struct uwsgi_route *ur, char *arg) {
return 0;
}
// force content length
static int transform_forcecl(struct wsgi_request *wsgi_req, struct uwsgi_transformation *ut) {
char buf[sizeof(UMAX64_STR)+1];
int ret = snprintf(buf, sizeof(UMAX64_STR)+1, "%llu", (unsigned long long) ut->chunk->pos);
if (ret <= 0 || ret >= (int) (sizeof(UMAX64_STR)+1)) {
wsgi_req->write_errors++;
return -1;
}
// do not check for errors !!!
uwsgi_response_add_header_force(wsgi_req, "Content-Length", 14, buf, ret);
return 0;
}
static int uwsgi_router_forcecl_func(struct wsgi_request *wsgi_req, struct uwsgi_route *route) {
uwsgi_add_transformation(wsgi_req, transform_forcecl, NULL);
return UWSGI_ROUTE_NEXT;
}
static int uwsgi_router_forcecl(struct uwsgi_route *ur, char *arg) {
ur->func = uwsgi_router_forcecl_func;
return 0;
}
// log route
static int uwsgi_router_log_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
@@ -1215,27 +1194,6 @@ static int uwsgi_router_setpathinfo(struct uwsgi_route *ur, char *arg) {
return 0;
}
// fixpathinfo route
static int uwsgi_router_fixpathinfo_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
if (wsgi_req->script_name_len == 0)
return UWSGI_ROUTE_NEXT;
char *ptr = uwsgi_req_append(wsgi_req, "PATH_INFO", 9, wsgi_req->path_info+wsgi_req->script_name_len, wsgi_req->path_info_len - wsgi_req->script_name_len);
if (!ptr) {
return UWSGI_ROUTE_BREAK;
}
wsgi_req->path_info = wsgi_req->path_info+wsgi_req->script_name_len;
wsgi_req->path_info_len = wsgi_req->path_info_len - wsgi_req->script_name_len;
return UWSGI_ROUTE_NEXT;
}
static int uwsgi_router_fixpathinfo(struct uwsgi_route *ur, char *arg) {
ur->func = uwsgi_router_fixpathinfo_func;
ur->data = arg;
ur->data_len = strlen(arg);
return 0;
}
// setscheme route
static int uwsgi_router_setscheme_func(struct wsgi_request *wsgi_req, struct uwsgi_route *ur) {
char **subject = (char **) (((char *)(wsgi_req))+ur->subject);
@@ -1799,10 +1757,6 @@ static char *uwsgi_route_var_uwsgi(struct wsgi_request *wsgi_req, char *key, uin
ret = uwsgi_64bit2str(wsgi_req->response_size);
*vallen = strlen(ret);
}
else if (!uwsgi_strncmp(key, keylen, "sor", 3)) {
ret = uwsgi_64bit2str(wsgi_req->start_of_request);
*vallen = strlen(ret);
}
return ret;
}
@@ -1839,10 +1793,6 @@ static char *uwsgi_route_var_time(struct wsgi_request *wsgi_req, char *key, uint
ret = uwsgi_num2str(uwsgi_now());
*vallen = strlen(ret);
}
else if (!uwsgi_strncmp(key, keylen, "micros", 6)) {
ret = uwsgi_64bit2str(uwsgi_micros());
*vallen = strlen(ret);
}
return ret;
}
@@ -1869,32 +1819,6 @@ static char *uwsgi_route_var_hex(struct wsgi_request *wsgi_req, char *key, uint1
return ret;
}
static char *uwsgi_route_var_upper(struct wsgi_request *wsgi_req, char *key, uint16_t keylen, uint16_t *vallen) {
char *ret = NULL;
char *var_value = uwsgi_get_var(wsgi_req, key, keylen, vallen);
if (var_value) {
ret = uwsgi_malloc((size_t) *vallen);
size_t i;
for (i = 0; i < *vallen; i++) {
ret[i] = toupper((int) var_value[i]);
}
}
return ret;
}
static char *uwsgi_route_var_lower(struct wsgi_request *wsgi_req, char *key, uint16_t keylen, uint16_t *vallen) {
char *ret = NULL;
char *var_value = uwsgi_get_var(wsgi_req, key, keylen, vallen);
if (var_value) {
ret = uwsgi_malloc((size_t) *vallen);
size_t i;
for (i = 0; i < *vallen; i++) {
ret[i] = tolower((int) var_value[i]);
}
}
return ret;
}
// register embedded routers
void uwsgi_register_embedded_routers() {
uwsgi_register_router("continue", uwsgi_router_continue);
@@ -1926,7 +1850,6 @@ void uwsgi_register_embedded_routers() {
uwsgi_register_router("seturi", uwsgi_router_seturi);
uwsgi_register_router("setremoteaddr", uwsgi_router_setremoteaddr);
uwsgi_register_router("setpathinfo", uwsgi_router_setpathinfo);
uwsgi_register_router("fixpathinfo", uwsgi_router_fixpathinfo);
uwsgi_register_router("setdocroot", uwsgi_router_setdocroot);
uwsgi_register_router("setscheme", uwsgi_router_setscheme);
uwsgi_register_router("setprocname", uwsgi_router_setprocname);
@@ -1942,7 +1865,6 @@ void uwsgi_register_embedded_routers() {
uwsgi_register_router("flush", uwsgi_router_flush);
uwsgi_register_router("fixcl", uwsgi_router_fixcl);
uwsgi_register_router("forcecl", uwsgi_router_forcecl);
uwsgi_register_router("harakiri", uwsgi_router_harakiri);
@@ -1989,10 +1911,6 @@ void uwsgi_register_embedded_routers() {
urv = uwsgi_register_route_var("hex", uwsgi_route_var_hex);
urv->need_free = 1;
urv = uwsgi_register_route_var("upper", uwsgi_route_var_upper);
urv->need_free = 1;
urv = uwsgi_register_route_var("lower", uwsgi_route_var_lower);
urv->need_free = 1;
}
struct uwsgi_router *uwsgi_register_router(char *name, int (*func) (struct uwsgi_route *, char *)) {
+1 -6
View File
@@ -7,11 +7,6 @@ int uwsgi_register_rpc(char *name, struct uwsgi_plugin *plugin, uint8_t args, vo
struct uwsgi_rpc *urpc;
int ret = -1;
if (!uwsgi.workers || !uwsgi.shared || !uwsgi.rpc_table_lock) {
uwsgi_log("RPC subsystem still not initialized\n");
return -1;
}
if (uwsgi.mywid == 0 && uwsgi.workers[0].pid != uwsgi.mypid) {
uwsgi_log("only the master and the workers can register RPC functions\n");
return -1;
@@ -145,7 +140,7 @@ char *uwsgi_do_rpc(char *node, char *func, uint8_t argc, char *argv[], uint16_t
// set the uwsgi header
uh = (struct uwsgi_header *) buffer;
uh->modifier1 = 173;
uh->_pktsize = buffer_size;
uh->pktsize = buffer_size;
uh->modifier2 = 0;
// add func to the array
+9 -9
View File
@@ -280,8 +280,8 @@ struct uwsgi_sharedarea *uwsgi_sharedarea_init_fd(int fd, uint64_t len, off_t of
}
uwsgi.sharedareas[id]->id = id;
uwsgi.sharedareas[id]->fd = fd;
uwsgi.sharedareas[id]->pages = len / (size_t) uwsgi.page_size;
if (len % (size_t) uwsgi.page_size != 0) uwsgi.sharedareas[id]->pages++;
uwsgi.sharedareas[id]->pages = len / uwsgi.page_size;
if (len % uwsgi.page_size != 0) uwsgi.sharedareas[id]->pages++;
uwsgi.sharedareas[id]->max_pos = len-1;
char *id_str = uwsgi_num2str(id);
uwsgi.sharedareas[id]->lock = uwsgi_rwlock_init(uwsgi_concat2("sharedarea", id_str));
@@ -292,12 +292,12 @@ struct uwsgi_sharedarea *uwsgi_sharedarea_init_fd(int fd, uint64_t len, off_t of
struct uwsgi_sharedarea *uwsgi_sharedarea_init(int pages) {
int id = uwsgi_sharedarea_new_id();
uwsgi.sharedareas[id] = uwsgi_calloc_shared((size_t)uwsgi.page_size * (size_t)(pages + 1));
uwsgi.sharedareas[id]->area = ((char *) uwsgi.sharedareas[id]) + (size_t) uwsgi.page_size;
uwsgi.sharedareas[id] = uwsgi_calloc_shared(uwsgi.page_size * (pages + 1));
uwsgi.sharedareas[id]->area = ((char *) uwsgi.sharedareas[id]) + uwsgi.page_size;
uwsgi.sharedareas[id]->id = id;
uwsgi.sharedareas[id]->fd = -1;
uwsgi.sharedareas[id]->pages = pages;
uwsgi.sharedareas[id]->max_pos = ((size_t)uwsgi.page_size * (size_t)pages) -1;
uwsgi.sharedareas[id]->max_pos = (uwsgi.page_size * pages) -1;
char *id_str = uwsgi_num2str(id);
uwsgi.sharedareas[id]->lock = uwsgi_rwlock_init(uwsgi_concat2("sharedarea", id_str));
free(id_str);
@@ -310,8 +310,8 @@ struct uwsgi_sharedarea *uwsgi_sharedarea_init_ptr(char *area, uint64_t len) {
uwsgi.sharedareas[id]->area = area;
uwsgi.sharedareas[id]->id = id;
uwsgi.sharedareas[id]->fd = -1;
uwsgi.sharedareas[id]->pages = len / (size_t) uwsgi.page_size;
if (len % (size_t) uwsgi.page_size != 0) uwsgi.sharedareas[id]->pages++;
uwsgi.sharedareas[id]->pages = len / uwsgi.page_size;
if (len % uwsgi.page_size != 0) uwsgi.sharedareas[id]->pages++;
uwsgi.sharedareas[id]->max_pos = len-1;
char *id_str = uwsgi_num2str(id);
uwsgi.sharedareas[id]->lock = uwsgi_rwlock_init(uwsgi_concat2("sharedarea", id_str));
@@ -348,8 +348,8 @@ struct uwsgi_sharedarea *uwsgi_sharedarea_init_keyval(char *arg) {
else {
len = uwsgi_n64(s_size);
}
pages = len / (size_t) uwsgi.page_size;
if (len % (size_t) uwsgi.page_size != 0) pages++;
pages = len / uwsgi.page_size;
if (len % uwsgi.page_size != 0) pages++;
}
if (s_offset) {
+16 -17
View File
@@ -2,7 +2,7 @@
extern struct uwsgi_server uwsgi;
int uwsgi_signal_handler(struct wsgi_request *wsgi_req, uint8_t sig) {
int uwsgi_signal_handler(uint8_t sig) {
struct uwsgi_signal_entry *use = NULL;
@@ -41,12 +41,12 @@ int uwsgi_signal_handler(struct wsgi_request *wsgi_req, uint8_t sig) {
// set harakiri here (if required and if i am a worker)
if (uwsgi.mywid > 0 && wsgi_req) {
if (uwsgi.mywid > 0) {
uwsgi.workers[uwsgi.mywid].sig = 1;
uwsgi.workers[uwsgi.mywid].signum = sig;
uwsgi.workers[uwsgi.mywid].signals++;
if (uwsgi.harakiri_options.workers > 0) {
set_harakiri(wsgi_req, uwsgi.harakiri_options.workers);
set_harakiri(uwsgi.harakiri_options.workers);
}
}
else if (uwsgi.muleid > 0) {
@@ -65,10 +65,10 @@ int uwsgi_signal_handler(struct wsgi_request *wsgi_req, uint8_t sig) {
int ret = uwsgi.p[use->modifier1]->signal_handler(sig, use->handler);
if (uwsgi.mywid > 0 && wsgi_req) {
if (uwsgi.mywid > 0) {
uwsgi.workers[uwsgi.mywid].sig = 0;
if (uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].harakiri > 0) {
set_harakiri(wsgi_req, 0);
if (uwsgi.workers[uwsgi.mywid].harakiri > 0) {
set_harakiri(0);
}
}
else if (uwsgi.muleid > 0) {
@@ -266,7 +266,7 @@ int uwsgi_remote_signal_send(char *addr, uint8_t sig) {
struct uwsgi_header uh;
uh.modifier1 = 110;
uh._pktsize = 0;
uh.pktsize = 0;
uh.modifier2 = sig;
int fd = uwsgi_connect(addr, 0, 1);
@@ -415,7 +415,7 @@ void uwsgi_route_signal(uint8_t sig) {
}
int uwsgi_signal_wait(struct wsgi_request *wsgi_req, int signum) {
int uwsgi_signal_wait(int signum) {
int wait_for_specific_signal = 0;
uint8_t uwsgi_signal = 0;
@@ -440,7 +440,7 @@ cycle:
uwsgi_error("read()");
}
else {
(void) uwsgi_signal_handler(wsgi_req, uwsgi_signal);
(void) uwsgi_signal_handler(uwsgi_signal);
if (wait_for_specific_signal) {
if (signum != uwsgi_signal)
goto cycle;
@@ -453,7 +453,7 @@ cycle:
uwsgi_error("read()");
}
else {
(void) uwsgi_signal_handler(wsgi_req, uwsgi_signal);
(void) uwsgi_signal_handler(uwsgi_signal);
if (wait_for_specific_signal) {
if (signum != uwsgi_signal)
goto cycle;
@@ -467,7 +467,8 @@ cycle:
return received_signal;
}
int uwsgi_receive_signal(struct wsgi_request *wsgi_req, int fd, char *name, int id) {
void uwsgi_receive_signal(int fd, char *name, int id) {
uint8_t uwsgi_signal;
ssize_t ret = read(fd, &uwsgi_signal, 1);
@@ -483,18 +484,16 @@ int uwsgi_receive_signal(struct wsgi_request *wsgi_req, int fd, char *name, int
#ifdef UWSGI_DEBUG
uwsgi_log_verbose("master sent signal %d to %s %d\n", uwsgi_signal, name, id);
#endif
if (uwsgi_signal_handler(wsgi_req, uwsgi_signal)) {
if (uwsgi_signal_handler(uwsgi_signal)) {
uwsgi_log_verbose("error managing signal %d on %s %d\n", uwsgi_signal, name, id);
}
return 1;
}
return 0;
return;
destroy:
// better to kill the whole worker...
uwsgi_log_verbose("uWSGI %s %d screams: UAAAAAAH my master disconnected: I will kill myself!!!\n", name, id);
uwsgi_log_verbose("uWSGI %s %d screams: UAAAAAAH my master disconnected: i will kill myself !!!\n", name, id);
end_me(0);
// never here
return 0;
}
+1 -19
View File
@@ -51,8 +51,6 @@ char *uwsgi_getsockname(int fd) {
if (!getsockname(fd, gsa.sa, &socket_type_len)) {
if (gsa.sa->sa_family == AF_UNIX) {
// unnamed socket ?
if (socket_type_len == sizeof(sa_family_t)) return "";
if (usa.sa_un.sun_path[0] == 0) {
return uwsgi_concat2("@", usa.sa_un.sun_path + 1);
}
@@ -712,11 +710,6 @@ int bind_to_tcp(char *socket_name, int listen_queue, char *tcp_port) {
if (uwsgi.tcp_fast_open) {
#ifdef TCP_FASTOPEN
#ifndef SOL_TCP
#define SOL_TCP IPPROTO_TCP
#endif
if (setsockopt(serverfd, SOL_TCP, TCP_FASTOPEN, (const void *) &uwsgi.tcp_fast_open, sizeof(int)) < 0) {
uwsgi_error("TCP_FASTOPEN setsockopt()");
}
@@ -1256,20 +1249,10 @@ void uwsgi_add_socket_from_fd(struct uwsgi_socket *uwsgi_sock, int fd) {
}
void uwsgi_close_all_sockets() {
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
while (uwsgi_sock) {
if (uwsgi_sock->bound)
close(uwsgi_sock->fd);
uwsgi_sock = uwsgi_sock->next;
}
}
void uwsgi_close_all_unshared_sockets() {
struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
while (uwsgi_sock) {
if (uwsgi_sock->bound && !uwsgi_sock->shared)
if (uwsgi_sock->bound)
close(uwsgi_sock->fd);
uwsgi_sock = uwsgi_sock->next;
}
@@ -1957,7 +1940,6 @@ void uwsgi_protocols_register() {
uwsgi_register_protocol("puwsgi", uwsgi_proto_puwsgi_setup);
uwsgi_register_protocol("http", uwsgi_proto_http_setup);
uwsgi_register_protocol("http11", uwsgi_proto_http11_setup);
#ifdef UWSGI_SSL
uwsgi_register_protocol("suwsgi", uwsgi_proto_suwsgi_setup);
Executable → Regular
+28 -87
View File
@@ -1,13 +1,11 @@
#include "uwsgi.h"
#ifdef __sun__
#include "strings.h"
#endif
extern struct uwsgi_server uwsgi;
static void spooler_readdir(struct uwsgi_spooler *, char *dir);
#ifdef __linux__
static void spooler_scandir(struct uwsgi_spooler *, char *dir);
#endif
static void spooler_manage_task(struct uwsgi_spooler *, char *, char *);
// increment it whenever a signal is raised
@@ -303,9 +301,9 @@ char *uwsgi_spool_request(struct wsgi_request *wsgi_req, char *buf, size_t len,
struct uwsgi_header uh;
uh.modifier1 = 17;
uh.modifier2 = 0;
uh._pktsize = (uint16_t) len;
uh.pktsize = (uint16_t) len;
#ifdef __BIG_ENDIAN__
uh._pktsize = uwsgi_swap16(uh._pktsize);
uh.pktsize = uwsgi_swap16(uh.pktsize);
#endif
if (write(fd, &uh, 4) != 4) {
@@ -431,32 +429,25 @@ void spooler(struct uwsgi_spooler *uspool) {
// reset the tasks counter
uspool->tasks = 0;
time_t last_task_managed = 0;
for (;;) {
if (chdir(uspool->dir)) {
uwsgi_error("chdir()");
exit(1);
}
if (uwsgi.spooler_ordered) {
#ifdef __linux__
spooler_scandir(uspool, NULL);
#else
spooler_readdir(uspool, NULL);
#endif
}
else {
spooler_readdir(uspool, NULL);
}
// here we check (if in cheap mode), if the spooler has done its job
if (uwsgi.spooler_cheap) {
if (last_task_managed == uspool->last_task_managed) {
uwsgi_log_verbose("cheaping spooler %s ...\n", uspool->dir);
exit(0);
}
last_task_managed = uspool->last_task_managed;
}
int timeout = uwsgi.shared->spooler_frequency ? uwsgi.shared->spooler_frequency : uwsgi.spooler_frequency;
if (wakeup > 0) {
timeout = 0;
@@ -465,15 +456,7 @@ void spooler(struct uwsgi_spooler *uspool) {
if (event_queue_wait(spooler_event_queue, timeout, &interesting_fd) > 0) {
if (uwsgi.master_process) {
if (interesting_fd == uwsgi.shared->spooler_signal_pipe[1]) {
if (uwsgi_receive_signal(NULL, interesting_fd, "spooler", (int) getpid())) {
if (uwsgi.spooler_signal_as_task) {
uspool->tasks++;
if (uwsgi.spooler_max_tasks > 0 && uspool->tasks >= (uint64_t) uwsgi.spooler_max_tasks) {
uwsgi_log("[spooler %s pid: %d] maximum number of tasks reached (%d) recycling ...\n", uspool->dir, (int) uwsgi.mypid, uwsgi.spooler_max_tasks);
end_me(0);
}
}
}
uwsgi_receive_signal(interesting_fd, "spooler", (int) getpid());
}
}
}
@@ -488,6 +471,7 @@ void spooler(struct uwsgi_spooler *uspool) {
}
}
#ifdef __linux__
static void spooler_scandir(struct uwsgi_spooler *uspool, char *dir) {
struct dirent **tasklist;
@@ -496,11 +480,7 @@ static void spooler_scandir(struct uwsgi_spooler *uspool, char *dir) {
if (!dir)
dir = uspool->dir;
#ifdef __NetBSD__
n = scandir(dir, &tasklist, NULL, (void *)uwsgi_versionsort);
#else
n = scandir(dir, &tasklist, NULL, uwsgi_versionsort);
#endif
n = scandir(dir, &tasklist, 0, versionsort);
if (n < 0) {
uwsgi_error("scandir()");
return;
@@ -513,6 +493,7 @@ static void spooler_scandir(struct uwsgi_spooler *uspool, char *dir) {
free(tasklist);
}
#endif
static void spooler_readdir(struct uwsgi_spooler *uspool, char *dir) {
@@ -531,7 +512,7 @@ static void spooler_readdir(struct uwsgi_spooler *uspool, char *dir) {
closedir(sdir);
}
else {
uwsgi_error("spooler_readdir()/opendir()");
uwsgi_error("opendir()");
}
}
@@ -551,7 +532,6 @@ void spooler_manage_task(struct uwsgi_spooler *uspool, char *dir, char *task) {
if (!strncmp("uwsgi_spoolfile_on_", task, 19) || (uwsgi.spooler_ordered && is_a_number(task))) {
struct stat sf_lstat;
if (lstat(task, &sf_lstat)) {
return;
}
@@ -561,30 +541,26 @@ void spooler_manage_task(struct uwsgi_spooler *uspool, char *dir, char *task) {
return;
}
#ifdef __linux__
if (S_ISDIR(sf_lstat.st_mode) && uwsgi.spooler_ordered) {
if (chdir(task)) {
uwsgi_error("spooler_manage_task()/chdir()");
uwsgi_error("chdir()");
return;
}
#ifdef __UCLIBC__
char *prio_path = uwsgi_malloc(PATH_MAX);
realpath(".", prio_path);
#else
char *prio_path = realpath(".", NULL);
#endif
spooler_scandir(uspool, prio_path);
free(prio_path);
if (chdir(dir)) {
uwsgi_error("spooler_manage_task()/chdir()");
uwsgi_error("chdir()");
}
return;
}
#endif
if (!S_ISREG(sf_lstat.st_mode)) {
return;
}
if (!access(task, R_OK | W_OK)) {
spool_fd = open(task, O_RDWR);
if (spool_fd < 0) {
@@ -605,34 +581,33 @@ void spooler_manage_task(struct uwsgi_spooler *uspool, char *dir, char *task) {
return;
}
ssize_t rlen = uwsgi_protected_read(spool_fd, &uh, 4);
if (rlen != 4) {
// it could be here for broken file or just opened one
if (rlen < 0)
uwsgi_error("spooler_manage_task()/read()");
uwsgi_error("read()");
uwsgi_protected_close(spool_fd);
return;
}
#ifdef __BIG_ENDIAN__
uh._pktsize = uwsgi_swap16(uh._pktsize);
uh.pktsize = uwsgi_swap16(uh.pktsize);
#endif
if (uwsgi_protected_read(spool_fd, spool_buf, uh._pktsize) != uh._pktsize) {
uwsgi_error("spooler_manage_task()/read()");
if (uwsgi_protected_read(spool_fd, spool_buf, uh.pktsize) != uh.pktsize) {
uwsgi_error("read()");
destroy_spool(dir, task);
uwsgi_protected_close(spool_fd);
return;
}
// body available ?
if (sf_lstat.st_size > (uh._pktsize + 4)) {
body_len = sf_lstat.st_size - (uh._pktsize + 4);
if (sf_lstat.st_size > (uh.pktsize + 4)) {
body_len = sf_lstat.st_size - (uh.pktsize + 4);
body = uwsgi_malloc(body_len);
if ((size_t) uwsgi_protected_read(spool_fd, body, body_len) != body_len) {
uwsgi_error("spooler_manage_task()/read()");
uwsgi_error("read()");
destroy_spool(dir, task);
uwsgi_protected_close(spool_fd);
free(body);
@@ -640,10 +615,8 @@ void spooler_manage_task(struct uwsgi_spooler *uspool, char *dir, char *task) {
}
}
// now the task is running and should not be woken up
// now the task is running and should not be waken up
uspool->running = 1;
// this is used in cheap mode for making decision about who must die
uspool->last_task_managed = uwsgi_now();
if (!uwsgi.spooler_quiet)
uwsgi_log("[spooler %s pid: %d] managing request %s ...\n", uspool->dir, (int) uwsgi.mypid, task);
@@ -652,7 +625,7 @@ void spooler_manage_task(struct uwsgi_spooler *uspool, char *dir, char *task) {
// chdir before running the task (if requested)
if (uwsgi.spooler_chdir) {
if (chdir(uwsgi.spooler_chdir)) {
uwsgi_error("spooler_manage_task()/chdir()");
uwsgi_error("chdir()");
}
}
@@ -663,7 +636,7 @@ void spooler_manage_task(struct uwsgi_spooler *uspool, char *dir, char *task) {
if (uwsgi.harakiri_options.spoolers > 0) {
set_spooler_harakiri(uwsgi.harakiri_options.spoolers);
}
ret = uwsgi.p[i]->spooler(task, spool_buf, uh._pktsize, body, body_len);
ret = uwsgi.p[i]->spooler(task, spool_buf, uh.pktsize, body, body_len);
if (uwsgi.harakiri_options.spoolers > 0) {
set_spooler_harakiri(0);
}
@@ -710,35 +683,3 @@ void spooler_manage_task(struct uwsgi_spooler *uspool, char *dir, char *task) {
}
}
}
// this function checks which spooler should be spawned
void uwsgi_spooler_cheap_check() {
struct uwsgi_spooler *uspool = uwsgi.spoolers;
char *last_managed = NULL;
while(uspool) {
// skip already active spoolers
if (uspool->pid > 0) goto next;
// spooler dir names (in multiprocess mode, are ordered, so we can use
// this trick for avoiding spawning multiple processes for the same dir
// in the same cycle
if (!last_managed || strcmp(last_managed, uspool->dir)) {
// unfortunately, reusing readdir/scandir of the spooler is too dungeorus
// as the code is run in the master, let's do a simpler check
struct dirent *dp;
DIR *sdir = opendir(uspool->dir);
if (!sdir) goto next;
while ((dp = readdir(sdir)) != NULL) {
if (strncmp("uwsgi_spoolfile_on_", dp->d_name, 19)) continue;
// a uwsgi_spoolfile_on_* file has been found...
uspool->respawned++;
// spawn a new spooler
uspool->pid = spooler_start(uspool);
last_managed = uspool->dir;
break;
}
closedir(sdir);
}
next:
uspool = uspool->next;
}
}
+1 -19
View File
@@ -30,18 +30,7 @@ void uwsgi_ssl_info_cb(SSL const *ssl, int where, int ret) {
}
int uwsgi_ssl_verify_callback(int ok, X509_STORE_CTX * x509_store) {
if (!ok && uwsgi.ssl_verbose) {
char buf[256];
X509 *err_cert;
int depth;
int err;
depth = X509_STORE_CTX_get_error_depth(x509_store);
err_cert = X509_STORE_CTX_get_current_cert(x509_store);
X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256);
err = X509_STORE_CTX_get_error(x509_store);
uwsgi_log("[uwsgi-ssl] client certificate verify error: num=%d:%s:depth=%d:%s\n", err, X509_verify_cert_error_string(err), depth, buf);
}
return ok;
return 1;
}
int uwsgi_ssl_session_new_cb(SSL *ssl, SSL_SESSION *sess) {
@@ -514,13 +503,6 @@ clear:
}
char *uwsgi_sanitize_cert_filename(char *base, char *key, uint16_t keylen) {
// stop at the first slash if mountpoints are involved
if (uwsgi.subscription_mountpoints) {
char *slash = memchr(key, '/', keylen);
if (slash) {
keylen = slash - key;
}
}
uint16_t i;
char *filename = uwsgi_concat4n(base, strlen(base), "/", 1, key, keylen, ".pem\0", 5);
+14 -16
View File
@@ -167,9 +167,6 @@ static time_t parse_http_date(char *date, uint16_t len) {
}
time_t uwsgi_parse_http_date(char *buf, uint16_t len) {
return parse_http_date(buf, len);
}
int uwsgi_add_expires_type(struct wsgi_request *wsgi_req, char *mime_type, int mime_type_len, struct stat *st) {
@@ -459,28 +456,29 @@ int uwsgi_real_file_serve(struct wsgi_request *wsgi_req, char *real_filename, si
}
}
#ifdef UWSGI_DEBUG
uwsgi_log("[uwsgi-fileserve] file %s found, mimetype %s\n", real_filename, mime_type);
uwsgi_log("[uwsgi-fileserve] file %s found\n", real_filename);
#endif
// static file - don't update avg_rt after request
wsgi_req->do_not_account_avg_rt = 1;
size_t fsize = st->st_size;
// security check
if (wsgi_req->range_from > fsize) {
wsgi_req->range_from = 0;
wsgi_req->range_to = 0;
}
else {
fsize -= wsgi_req->range_from;
}
if (wsgi_req->range_to) {
fsize = (wsgi_req->range_to - wsgi_req->range_from)+1;
if (fsize + wsgi_req->range_from > (size_t) (st->st_size)) {
fsize = st->st_size - wsgi_req->range_from;
fsize = wsgi_req->range_to - wsgi_req->range_from;
if (fsize > (size_t)st->st_size) {
fsize = st->st_size;
}
}
else {
// reset in case of inconsistent size
if (wsgi_req->range_from > fsize) {
wsgi_req->range_from = 0;
fsize = 0;
}
else {
fsize -= wsgi_req->range_from;
}
}
// HTTP status
if (fsize > 0 && (wsgi_req->range_from || wsgi_req->range_to)) {
+3 -2
View File
@@ -569,13 +569,14 @@ static void stats_dump_var(char *k, uint16_t kl, char *v, uint16_t vl, void *dat
int uwsgi_stats_dump_vars(struct uwsgi_stats *us, struct uwsgi_core *uc) {
if (!uc->in_request) return 0;
uint64_t pktsize = uc->req.len;
struct uwsgi_header *uh = (struct uwsgi_header *) uc->buffer;
uint16_t pktsize = uh->pktsize;
if (!pktsize) return 0;
char *dst = uwsgi.workers[0].cores[0].buffer;
memcpy(dst, uc->buffer+4, uwsgi.buffer_size);
// ok now check if something changed...
if (!uc->in_request) return 0;
if (uc->req.len != pktsize) return 0;
if (uh->pktsize != pktsize) return 0;
if (memcmp(dst, uc->buffer+4, uwsgi.buffer_size)) return 0;
// nothing changed let's dump vars
int ret = uwsgi_hooked_parse(dst, pktsize, stats_dump_var, us);
+18 -22
View File
@@ -65,9 +65,16 @@ char *uwsgi_lower(char *str, size_t size) {
return str;
}
// check if a char is contained in a string
// check if a string is contained in another one
char *uwsgi_str_contains(char *str, int slen, char what) {
return memchr(str, what, slen);
int i;
for (i = 0; i < slen; i++) {
if (str[i] == what) {
return str + i;
}
}
return NULL;
}
int uwsgi_contains_n(char *s1, size_t s1_len, char *s2, size_t s2_len) {
@@ -119,7 +126,15 @@ int uwsgi_starts_with(char *src, int slen, char *dst, int dlen) {
// unsized check
int uwsgi_startswith(char *src, char *what, int wlen) {
return memcmp(what, src, wlen);
int i;
for (i = 0; i < wlen; i++) {
if (src[i] != what[i])
return -1;
}
return 0;
}
// concatenate strings
@@ -468,22 +483,3 @@ char ** uwsgi_split_quoted(char *what, size_t what_len, char *sep, size_t *rlen)
return ret;
}
char *uwsgi_get_last_char(char *what, char c) {
return strrchr(what, c);
}
// Note by Mathieu Dupuy: memrchr here is better, unfortunately it is not supported
// everywhere. The only safe option looks checking for Linux :(
char *uwsgi_get_last_charn(char *what, size_t len, char c) {
#if defined(__linux__)
return memrchr(what, c, len);
#else
while (len--) {
if (what[len] == c)
return what + len;
}
return NULL;
#endif
}
+162 -411
View File
@@ -20,17 +20,6 @@
extern struct uwsgi_server uwsgi;
char *uwsgi_subscription_algo_name(void *ptr) {
struct uwsgi_string_list *usl = uwsgi.subscription_algos;
while(usl) {
if (usl->custom_ptr == ptr) {
return usl->value;
}
usl = usl->next;
}
return NULL;
}
#ifdef UWSGI_SSL
static void uwsgi_subscription_sni_check(struct uwsgi_subscribe_slot *current_slot, struct uwsgi_subscribe_req *usr) {
if (usr->sni_key_len > 0 && usr->sni_crt_len > 0) {
@@ -83,8 +72,6 @@ int uwsgi_subscription_credentials_check(struct uwsgi_subscribe_slot *slot, stru
}
struct uwsgi_subscribe_slot *uwsgi_get_subscribe_slot(struct uwsgi_subscribe_slot **slot, char *key, uint16_t keylen) {
int retried = 0;
retry:
if (keylen > 0xff)
return NULL;
@@ -138,20 +125,136 @@ retry:
break;
}
// if we are here and in mountpoints mode, try the domain only variant
if (uwsgi.subscription_mountpoints && !retried) {
char *slash = memchr(key, '/', keylen);
if (slash) {
keylen = slash - key;
retried = 1;
goto retry;
}
}
return NULL;
}
struct uwsgi_subscribe_node *uwsgi_get_subscribe_node(struct uwsgi_subscribe_slot **slot, char *key, uint16_t keylen, struct uwsgi_subscription_client *client) {
// least reference count
static struct uwsgi_subscribe_node *uwsgi_subscription_algo_lrc(struct uwsgi_subscribe_slot *current_slot, struct uwsgi_subscribe_node *node) {
// if node is NULL we are in the second step (in lrc mode we do not use the first step)
if (node)
return NULL;
struct uwsgi_subscribe_node *choosen_node = NULL;
node = current_slot->nodes;
uint64_t min_rc = 0;
while (node) {
if (!node->death_mark) {
if (min_rc == 0 || node->reference < min_rc) {
min_rc = node->reference;
choosen_node = node;
if (min_rc == 0 && !(node->next && node->next->reference <= node->reference && node->next->last_requests <= node->last_requests))
break;
}
}
node = node->next;
}
if (choosen_node) {
choosen_node->reference++;
}
return choosen_node;
}
// weighted least reference count
static struct uwsgi_subscribe_node *uwsgi_subscription_algo_wlrc(struct uwsgi_subscribe_slot *current_slot, struct uwsgi_subscribe_node *node) {
// if node is NULL we are in the second step (in wlrc mode we do not use the first step)
if (node)
return NULL;
struct uwsgi_subscribe_node *choosen_node = NULL;
node = current_slot->nodes;
double min_rc = 0;
while (node) {
if (!node->death_mark) {
// node->weight is always >= 1, we can safely use it as divider
double ref = (double) node->reference / (double) node->weight;
double next_node_ref = 0;
if (node->next)
next_node_ref = (double) node->next->reference / (double) node->next->weight;
if (min_rc == 0 || ref < min_rc) {
min_rc = ref;
choosen_node = node;
if (min_rc == 0 && !(node->next && next_node_ref <= ref && node->next->last_requests <= node->last_requests))
break;
}
}
node = node->next;
}
if (choosen_node) {
choosen_node->reference++;
}
return choosen_node;
}
// weighted round robin algo
static struct uwsgi_subscribe_node *uwsgi_subscription_algo_wrr(struct uwsgi_subscribe_slot *current_slot, struct uwsgi_subscribe_node *node) {
// if node is NULL we are in the second step
if (node) {
if (node->death_mark == 0 && node->wrr > 0) {
node->wrr--;
node->reference++;
return node;
}
return NULL;
}
// no wrr > 0 node found, reset them
node = current_slot->nodes;
uint64_t min_weight = 0;
while (node) {
if (!node->death_mark) {
if (min_weight == 0 || node->weight < min_weight)
min_weight = node->weight;
}
node = node->next;
}
// now set wrr
node = current_slot->nodes;
struct uwsgi_subscribe_node *choosen_node = NULL;
while (node) {
if (!node->death_mark) {
node->wrr = node->weight / min_weight;
choosen_node = node;
}
node = node->next;
}
if (choosen_node) {
choosen_node->wrr--;
choosen_node->reference++;
}
return choosen_node;
}
void uwsgi_subscription_set_algo(char *algo) {
if (!algo)
goto wrr;
if (!strcmp(algo, "wrr")) {
uwsgi.subscription_algo = uwsgi_subscription_algo_wrr;
return;
}
if (!strcmp(algo, "lrc")) {
uwsgi.subscription_algo = uwsgi_subscription_algo_lrc;
return;
}
if (!strcmp(algo, "wlrc")) {
uwsgi.subscription_algo = uwsgi_subscription_algo_wlrc;
return;
}
wrr:
uwsgi.subscription_algo = uwsgi_subscription_algo_wrr;
}
struct uwsgi_subscribe_node *uwsgi_get_subscribe_node(struct uwsgi_subscribe_slot **slot, char *key, uint16_t keylen) {
if (keylen > 0xff)
return NULL;
@@ -184,14 +287,14 @@ struct uwsgi_subscribe_node *uwsgi_get_subscribe_node(struct uwsgi_subscribe_slo
continue;
}
struct uwsgi_subscribe_node *choosen_node = current_slot->algo(current_slot, node, client);
struct uwsgi_subscribe_node *choosen_node = uwsgi.subscription_algo(current_slot, node);
if (choosen_node)
return choosen_node;
node = node->next;
}
return current_slot->algo(current_slot, node, client);
return uwsgi.subscription_algo(current_slot, node);
}
struct uwsgi_subscribe_node *uwsgi_get_subscribe_node_by_name(struct uwsgi_subscribe_slot **slot, char *key, uint16_t keylen, char *val, uint16_t vallen) {
@@ -333,10 +436,6 @@ struct uwsgi_subscribe_node *uwsgi_add_subscribe_node(struct uwsgi_subscribe_slo
node->cores = usr->cores;
node->load = usr->load;
node->weight = usr->weight;
node->backup_level = usr->backup_level;
if (usr->proto_len > 0) {
node->proto = usr->proto[0];
}
if (!node->weight)
node->weight = 1;
node->last_requests = 0;
@@ -369,10 +468,6 @@ struct uwsgi_subscribe_node *uwsgi_add_subscribe_node(struct uwsgi_subscribe_slo
node->cores = usr->cores;
node->load = usr->load;
node->weight = usr->weight;
node->backup_level = usr->backup_level;
if (usr->proto_len > 0) {
node->proto = usr->proto[0];
}
node->unix_check = usr->unix_check;
if (!node->weight)
node->weight = 1;
@@ -393,7 +488,7 @@ struct uwsgi_subscribe_node *uwsgi_add_subscribe_node(struct uwsgi_subscribe_slo
}
node->next = NULL;
uwsgi_log("[uwsgi-subscription for pid %d] %.*s => new node: %.*s (weight: %d, backup: %d)\n", (int) uwsgi.mypid, usr->keylen, usr->key, usr->address_len, usr->address, usr->weight, usr->backup_level);
uwsgi_log("[uwsgi-subscription for pid %d] %.*s => new node: %.*s\n", (int) uwsgi.mypid, usr->keylen, usr->key, usr->address_len, usr->address);
if (node->notify[0]) {
char buf[1024];
int ret = snprintf(buf, 1024, "[subscription ack] %.*s => new node: %.*s", usr->keylen, usr->key, usr->address_len, usr->address);
@@ -444,10 +539,6 @@ struct uwsgi_subscribe_node *uwsgi_add_subscribe_node(struct uwsgi_subscribe_slo
current_slot->nodes->cores = usr->cores;
current_slot->nodes->load = usr->load;
current_slot->nodes->weight = usr->weight;
current_slot->nodes->backup_level = usr->backup_level;
if (usr->proto_len > 0) {
current_slot->nodes->proto = usr->proto[0];
}
current_slot->nodes->unix_check = usr->unix_check;
if (!current_slot->nodes->weight)
current_slot->nodes->weight = 1;
@@ -479,16 +570,13 @@ struct uwsgi_subscribe_node *uwsgi_add_subscribe_node(struct uwsgi_subscribe_slo
current_slot->prev = old_slot;
current_slot->next = NULL;
current_slot->algo = usr->algo;
if (!current_slot->algo) current_slot->algo = uwsgi.subscription_algo;
if (!slot[hash_key] || current_slot->prev == NULL) {
slot[hash_key] = current_slot;
}
uwsgi_log("[uwsgi-subscription for pid %d] new pool: %.*s (hash key: %d, algo: %s)\n", (int) uwsgi.mypid, usr->keylen, usr->key, current_slot->hash, uwsgi_subscription_algo_name(current_slot->algo));
uwsgi_log("[uwsgi-subscription for pid %d] %.*s => new node: %.*s (weight: %d, backup: %d)\n", (int) uwsgi.mypid, usr->keylen, usr->key, usr->address_len, usr->address, usr->weight, usr->backup_level);
uwsgi_log("[uwsgi-subscription for pid %d] new pool: %.*s (hash key: %d)\n", (int) uwsgi.mypid, usr->keylen, usr->key, current_slot->hash);
uwsgi_log("[uwsgi-subscription for pid %d] %.*s => new node: %.*s\n", (int) uwsgi.mypid, usr->keylen, usr->key, usr->address_len, usr->address);
if (current_slot->nodes->notify[0]) {
char buf[1024];
@@ -581,30 +669,6 @@ static void send_subscription(int sfd, char *host, char *message, uint16_t messa
close(fd);
}
static int uwsgi_subscription_ub_fix(struct uwsgi_buffer *ub, uint8_t modifier1, uint8_t modifier2, uint8_t cmd, char *sign) {
#ifdef UWSGI_SSL
if (sign) {
if (uwsgi_buffer_append_keynum(ub, "unix", 4, (uwsgi_now() + (time_t) cmd)))
return -1;
unsigned int signature_len = 0;
char *signature = uwsgi_rsa_sign(sign, ub->buf + 4, ub->pos - 4, &signature_len);
if (signature && signature_len > 0) {
if (uwsgi_buffer_append_keyval(ub, "sign", 4, signature, signature_len)) {
free(signature);
return -1;
}
free(signature);
}
}
#endif
// add uwsgi header
if (uwsgi_buffer_set_uh(ub, 224, cmd)) return -1;
return 0;
}
static struct uwsgi_buffer *uwsgi_subscription_ub(char *key, size_t keysize, uint8_t modifier1, uint8_t modifier2, uint8_t cmd, char *socket_name, char *sign, char *sni_key, char *sni_crt, char *sni_ca) {
struct uwsgi_buffer *ub = uwsgi_buffer_new(4096);
@@ -660,7 +724,26 @@ static struct uwsgi_buffer *uwsgi_subscription_ub(char *key, size_t keysize, uin
goto end;
}
if (uwsgi_subscription_ub_fix(ub, modifier1, modifier2, cmd, sign)) goto end;
#ifdef UWSGI_SSL
if (sign) {
if (uwsgi_buffer_append_keynum(ub, "unix", 4, (uwsgi_now() + (time_t) cmd)))
goto end;
unsigned int signature_len = 0;
char *signature = uwsgi_rsa_sign(sign, ub->buf + 4, ub->pos - 4, &signature_len);
if (signature && signature_len > 0) {
if (uwsgi_buffer_append_keyval(ub, "sign", 4, signature, signature_len)) {
free(signature);
goto end;
}
free(signature);
}
}
#endif
// add uwsgi header
if (uwsgi_buffer_set_uh(ub, 224, cmd))
goto end;
return ub;
@@ -782,6 +865,13 @@ int uwsgi_no_subscriptions(struct uwsgi_subscribe_slot **slot) {
return 1;
}
struct uwsgi_subscribe_slot **uwsgi_subscription_init_ht() {
if (!uwsgi.subscription_algo) {
uwsgi_subscription_set_algo(NULL);
}
return uwsgi_calloc(sizeof(struct uwsgi_subscription_slot *) * UMAX16);
}
void uwsgi_subscribe(char *subscription, uint8_t cmd) {
size_t subfile_size;
@@ -928,28 +1018,8 @@ void uwsgi_subscribe2(char *arg, uint8_t cmd) {
char *s2_sni_key = NULL;
char *s2_sni_crt = NULL;
char *s2_sni_ca = NULL;
char *s2_proto = NULL;
char *s2_algo = NULL;
char *s2_backup = NULL;
struct uwsgi_buffer *ub = NULL;
if (uwsgi_kvlist_parse(arg, strlen(arg), ',', '=',
"server", &s2_server,
"key", &s2_key,
"socket", &s2_socket,
"addr", &s2_addr,
"weight", &s2_weight,
"modifier1", &s2_modifier1,
"modifier2", &s2_modifier2,
"sign", &s2_sign,
"check", &s2_check,
"sni_key", &s2_sni_key,
"sni_crt", &s2_sni_crt,
"sni_ca", &s2_sni_ca,
"proto", &s2_proto,
"algo", &s2_algo,
"backup", &s2_backup,
NULL)) {
if (uwsgi_kvlist_parse(arg, strlen(arg), ',', '=', "server", &s2_server, "key", &s2_key, "socket", &s2_socket, "addr", &s2_addr, "weight", &s2_weight, "modifier1", &s2_modifier1, "modifier2", &s2_modifier2, "sign", &s2_sign, "check", &s2_check, "sni_key", &s2_sni_key, "sni_crt", &s2_sni_crt, "sni_ca", &s2_sni_ca, NULL)) {
return;
}
@@ -961,15 +1031,8 @@ void uwsgi_subscribe2(char *arg, uint8_t cmd) {
goto end;
}
int weight = 1;
int backup = 0;
if (uwsgi.auto_weight) weight = uwsgi.numproc * uwsgi.cores;
if (s2_weight) {
weight = atoi(s2_weight);
}
if (s2_backup) {
backup = atoi(s2_backup);
uwsgi.weight = atoi(s2_weight);
}
if (s2_socket) {
@@ -993,76 +1056,8 @@ void uwsgi_subscribe2(char *arg, uint8_t cmd) {
modifier2 = atoi(s2_modifier2);
}
if (s2_addr == NULL) {
// no socket... no subscription
if (!uwsgi.sockets) goto end;
s2_addr = uwsgi_str(uwsgi.sockets->name);
}
ub = uwsgi_buffer_new(uwsgi.page_size);
if (!ub) goto end;
// leave space for the header
ub->pos = 4;
if (uwsgi_buffer_append_keyval(ub, "key", 3, s2_key, strlen(s2_key)))
goto end;
if (uwsgi_buffer_append_keyval(ub, "address", 7, s2_addr, strlen(s2_addr)))
goto end;
if (uwsgi_buffer_append_keynum(ub, "modifier1", 9, modifier1))
goto end;
if (uwsgi_buffer_append_keynum(ub, "modifier2", 9, modifier2))
goto end;
if (uwsgi_buffer_append_keynum(ub, "cores", 5, uwsgi.numproc * uwsgi.cores))
goto end;
if (uwsgi_buffer_append_keynum(ub, "load", 4, uwsgi.shared->load))
goto end;
if (uwsgi_buffer_append_keynum(ub, "weight", 6, weight))
goto end;
if (uwsgi_buffer_append_keynum(ub, "backup", 6, backup))
goto end;
if (s2_sni_key) {
if (uwsgi_buffer_append_keyval(ub, "sni_key", 7, s2_sni_key, strlen(s2_sni_key)))
goto end;
}
if (s2_sni_crt) {
if (uwsgi_buffer_append_keyval(ub, "sni_crt", 7, s2_sni_crt, strlen(s2_sni_crt)))
goto end;
}
if (s2_sni_ca) {
if (uwsgi_buffer_append_keyval(ub, "sni_ca", 6, s2_sni_ca, strlen(s2_sni_ca)))
goto end;
}
if (s2_proto) {
if (uwsgi_buffer_append_keyval(ub, "proto", 5, s2_proto, strlen(s2_proto)))
goto end;
}
if (s2_algo) {
if (uwsgi_buffer_append_keyval(ub, "algo", 4, s2_algo, strlen(s2_algo)))
goto end;
}
if (uwsgi.subscription_notify_socket) {
if (uwsgi_buffer_append_keyval(ub, "notify", 6, uwsgi.subscription_notify_socket, strlen(uwsgi.subscription_notify_socket)))
goto end;
}
else if (uwsgi.notify_socket_fd > -1 && uwsgi.notify_socket) {
if (uwsgi_buffer_append_keyval(ub, "notify", 6, uwsgi.notify_socket, strlen(uwsgi.notify_socket)))
goto end;
}
if (uwsgi_subscription_ub_fix(ub, modifier1, modifier2, cmd, s2_sign)) goto end;
send_subscription(-1, s2_server, ub->buf, ub->pos);
uwsgi_send_subscription(s2_server, s2_key, strlen(s2_key), modifier1, modifier2, cmd, s2_addr, s2_sign, s2_sni_key, s2_sni_crt, s2_sni_ca);
end:
if (ub)
uwsgi_buffer_destroy(ub);
if (s2_server)
free(s2_server);
if (s2_key)
@@ -1087,12 +1082,6 @@ end:
free(s2_sni_key);
if (s2_sni_ca)
free(s2_sni_ca);
if (s2_proto)
free(s2_proto);
if (s2_algo)
free(s2_algo);
if (s2_backup)
free(s2_backup);
}
void uwsgi_subscribe_all(uint8_t cmd, int verbose) {
@@ -1120,241 +1109,3 @@ void uwsgi_subscribe_all(uint8_t cmd, int verbose) {
}
}
// iphash
static struct uwsgi_subscribe_node *uwsgi_subscription_algo_iphash(struct uwsgi_subscribe_slot *current_slot, struct uwsgi_subscribe_node *node, struct uwsgi_subscription_client *client) {
// if node is NULL we are in the second step (in lrc mode we do not use the first step)
if (node)
return NULL;
// iphash does not support requests without client data
if (!client) return NULL;
if (!client->sockaddr) return NULL;
uint64_t count = 0;
// first step is counting the number of nodes
node = current_slot->nodes;
while(node) {
if (!node->death_mark) count++;
node = node->next;
}
if (count == 0) return NULL;
uint64_t hash = 0;
//hash the ip
if (client->sockaddr->sa.sa_family == AF_INET) {
hash = client->sockaddr->sa_in.sin_addr.s_addr % count;
}
#ifdef AF_INET6
else if (client->sockaddr->sa.sa_family == AF_INET6) {
hash = djb33x_hash((char *)client->sockaddr->sa_in6.sin6_addr.s6_addr, 16) % count;
}
#endif
// now re-iterate until count matches;
count = 0;
struct uwsgi_subscribe_node *choosen_node = NULL;
node = current_slot->nodes;
while (node) {
if (!node->death_mark) {
if (count == hash) {
choosen_node = node;
break;
}
count++;
}
node = node->next;
}
if (choosen_node) {
choosen_node->reference++;
}
return choosen_node;
}
// least reference count
static struct uwsgi_subscribe_node *uwsgi_subscription_algo_lrc(struct uwsgi_subscribe_slot *current_slot, struct uwsgi_subscribe_node *node, struct uwsgi_subscription_client *client) {
uint64_t backup_level = 0;
uint64_t has_backup = 0;
// if node is NULL we are in the second step (in lrc mode we do not use the first step)
if (node)
return NULL;
struct uwsgi_subscribe_node *choosen_node = NULL;
retry:
node = current_slot->nodes;
uint64_t min_rc = 0;
while (node) {
if (!node->death_mark) {
if (node->backup_level == backup_level) {
if (min_rc == 0 || node->reference < min_rc) {
min_rc = node->reference;
choosen_node = node;
if (min_rc == 0 && !(node->next && node->next->reference <= node->reference && node->next->last_requests <= node->last_requests))
break;
}
}
else if (node->backup_level > backup_level && (!has_backup || has_backup > node->backup_level)) {
has_backup = node->backup_level;
}
}
node = node->next;
}
if (choosen_node) {
choosen_node->reference++;
}
else if (has_backup) {
backup_level = has_backup;
goto retry;
}
return choosen_node;
}
// weighted least reference count
static struct uwsgi_subscribe_node *uwsgi_subscription_algo_wlrc(struct uwsgi_subscribe_slot *current_slot, struct uwsgi_subscribe_node *node, struct uwsgi_subscription_client *client) {
uint64_t backup_level = 0;
uint64_t has_backup = 0;
// if node is NULL we are in the second step (in wlrc mode we do not use the first step)
if (node)
return NULL;
struct uwsgi_subscribe_node *choosen_node = NULL;
retry:
node = current_slot->nodes;
has_backup = 0;
double min_rc = 0;
while (node) {
if (!node->death_mark) {
if (node->backup_level == backup_level) {
// node->weight is always >= 1, we can safely use it as divider
double ref = (double) node->reference / (double) node->weight;
double next_node_ref = 0;
if (node->next)
next_node_ref = (double) node->next->reference / (double) node->next->weight;
if (min_rc == 0 || ref < min_rc) {
min_rc = ref;
choosen_node = node;
if (min_rc == 0 && !(node->next && next_node_ref <= ref && node->next->last_requests <= node->last_requests))
break;
}
}
else if (node->backup_level > backup_level && (!has_backup || has_backup > node->backup_level)) {
has_backup = node->backup_level;
}
}
node = node->next;
}
if (choosen_node) {
choosen_node->reference++;
}
else if (has_backup) {
backup_level = has_backup;
goto retry;
}
return choosen_node;
}
// weighted round robin algo (with backup support)
static struct uwsgi_subscribe_node *uwsgi_subscription_algo_wrr(struct uwsgi_subscribe_slot *current_slot, struct uwsgi_subscribe_node *node, struct uwsgi_subscription_client *client) {
uint64_t backup_level = 0;
uint64_t has_backup = 0;
// if node is NULL we are in the second step
if (node) {
if (node->death_mark == 0 && node->wrr > 0) {
node->wrr--;
node->reference++;
return node;
}
return NULL;
}
// no wrr > 0 node found, reset them
node = current_slot->nodes;
uint64_t min_weight = 0;
while (node) {
if (!node->death_mark) {
if (min_weight == 0 || node->weight < min_weight)
min_weight = node->weight;
}
node = node->next;
}
// now set wrr
retry:
node = current_slot->nodes;
has_backup = 0;
struct uwsgi_subscribe_node *choosen_node = NULL;
while (node) {
if (!node->death_mark) {
if (node->backup_level == backup_level) {
node->wrr = node->weight / min_weight;
choosen_node = node;
}
else if (node->backup_level > backup_level && (!has_backup || has_backup > node->backup_level)) {
has_backup = node->backup_level;
}
}
node = node->next;
}
if (choosen_node) {
choosen_node->wrr--;
choosen_node->reference++;
}
else if (has_backup) {
backup_level = has_backup;
goto retry;
}
return choosen_node;
}
void uwsgi_subscription_init_algos() {
uwsgi_register_subscription_algo("wrr", uwsgi_subscription_algo_wrr);
uwsgi_register_subscription_algo("lrc", uwsgi_subscription_algo_lrc);
uwsgi_register_subscription_algo("wlrc", uwsgi_subscription_algo_wlrc);
uwsgi_register_subscription_algo("iphash", uwsgi_subscription_algo_iphash);
}
void uwsgi_subscription_set_algo(char *algo) {
if (!uwsgi.subscription_algos) {
uwsgi_subscription_init_algos();
}
if (!algo)
goto wrr;
uwsgi.subscription_algo = uwsgi_subscription_algo_get(algo, strlen(algo));
if (uwsgi.subscription_algo) return ;
wrr:
uwsgi.subscription_algo = uwsgi_subscription_algo_wrr;
}
// we are lazy for subscription algos, we initialize them only if needed
struct uwsgi_subscribe_slot **uwsgi_subscription_init_ht() {
if (!uwsgi.subscription_algo) {
uwsgi_subscription_set_algo(NULL);
}
return uwsgi_calloc(sizeof(struct uwsgi_subscription_slot *) * UMAX16);
}
struct uwsgi_subscribe_node *(*uwsgi_subscription_algo_get(char *name , size_t len))(struct uwsgi_subscribe_slot *, struct uwsgi_subscribe_node *, struct uwsgi_subscription_client *) {
struct uwsgi_string_list *usl = NULL;
uwsgi_foreach(usl, uwsgi.subscription_algos) {
if (!uwsgi_strncmp(usl->value, usl->len, name, len)) {
return (struct uwsgi_subscribe_node *(*)(struct uwsgi_subscribe_slot *, struct uwsgi_subscribe_node *, struct uwsgi_subscription_client *)) usl->custom_ptr;
}
}
return NULL;
}
void uwsgi_register_subscription_algo(char *name, struct uwsgi_subscribe_node *(*func)(struct uwsgi_subscribe_slot *, struct uwsgi_subscribe_node *, struct uwsgi_subscription_client *)) {
struct uwsgi_string_list *usl = uwsgi_string_new_list(&uwsgi.subscription_algos, name);
usl->custom_ptr = func;
}
Executable → Regular
+87 -169
View File
@@ -42,9 +42,9 @@ int check_hex(char *str, int len) {
}
// increase worker harakiri
void inc_harakiri(struct wsgi_request *wsgi_req, int sec) {
void inc_harakiri(int sec) {
if (uwsgi.master_process) {
uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].harakiri += sec;
uwsgi.workers[uwsgi.mywid].harakiri += sec;
}
else {
alarm(uwsgi.harakiri_options.workers + sec);
@@ -52,13 +52,12 @@ void inc_harakiri(struct wsgi_request *wsgi_req, int sec) {
}
// set worker harakiri
void set_harakiri(struct wsgi_request *wsgi_req, int sec) {
if (!wsgi_req) return;
void set_harakiri(int sec) {
if (sec == 0) {
uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].harakiri = 0;
uwsgi.workers[uwsgi.mywid].harakiri = 0;
}
else {
uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].harakiri = uwsgi_now() + sec;
uwsgi.workers[uwsgi.mywid].harakiri = uwsgi_now() + sec;
}
if (!uwsgi.master_process) {
alarm(sec);
@@ -66,7 +65,7 @@ void set_harakiri(struct wsgi_request *wsgi_req, int sec) {
}
// set user harakiri
void set_user_harakiri(struct wsgi_request *wsgi_req, int sec) {
void set_user_harakiri(int sec) {
if (!uwsgi.master_process) {
uwsgi_log("!!! unable to set user harakiri without the master process !!!\n");
return;
@@ -80,8 +79,8 @@ void set_user_harakiri(struct wsgi_request *wsgi_req, int sec) {
struct uwsgi_spooler *uspool = uwsgi.i_am_a_spooler;
uspool->user_harakiri = 0;
}
else if (wsgi_req) {
uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].user_harakiri = 0;
else {
uwsgi.workers[uwsgi.mywid].user_harakiri = 0;
}
}
else {
@@ -92,8 +91,8 @@ void set_user_harakiri(struct wsgi_request *wsgi_req, int sec) {
struct uwsgi_spooler *uspool = uwsgi.i_am_a_spooler;
uspool->user_harakiri = uwsgi_now() + sec;
}
else if (wsgi_req) {
uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].user_harakiri = uwsgi_now() + sec;
else {
uwsgi.workers[uwsgi.mywid].user_harakiri = uwsgi_now() + sec;
}
}
}
@@ -333,11 +332,9 @@ void uwsgi_as_root() {
if (getuid() > 0)
goto nonroot;
#ifndef __RUMP__
if (!uwsgi.master_as_root && !uwsgi.uidname) {
uwsgi_log_initial("uWSGI running as root, you can use --uid/--gid/--chroot options\n");
}
#endif
int in_jail = 0;
@@ -703,20 +700,20 @@ void uwsgi_as_root() {
}
uwsgi_foreach(usl, uwsgi.wait_for_fs) {
if (uwsgi_wait_for_fs(usl->value, 0)) exit(1);
}
if (uwsgi_wait_for_fs(usl->value, 0)) exit(1);
}
uwsgi_foreach(usl, uwsgi.wait_for_file) {
if (uwsgi_wait_for_fs(usl->value, 1)) exit(1);
}
uwsgi_foreach(usl, uwsgi.wait_for_file) {
if (uwsgi_wait_for_fs(usl->value, 1)) exit(1);
}
uwsgi_foreach(usl, uwsgi.wait_for_dir) {
if (uwsgi_wait_for_fs(usl->value, 2)) exit(1);
}
uwsgi_foreach(usl, uwsgi.wait_for_dir) {
if (uwsgi_wait_for_fs(usl->value, 2)) exit(1);
}
uwsgi_foreach(usl, uwsgi.wait_for_mountpoint) {
if (uwsgi_wait_for_mountpoint(usl->value)) exit(1);
}
uwsgi_foreach(usl, uwsgi.wait_for_mountpoint) {
if (uwsgi_wait_for_mountpoint(usl->value)) exit(1);
}
uwsgi_hooks_run(uwsgi.hook_as_root, "as root", 1);
@@ -895,7 +892,6 @@ void uwsgi_as_root() {
}
}
}
free(gids);
}
}
if (uwsgi.uid) {
@@ -907,11 +903,9 @@ void uwsgi_as_root() {
}
}
#ifndef __RUMP__
if (!getuid()) {
uwsgi_log_initial("*** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** \n");
}
#endif
#ifdef UWSGI_CAP
@@ -1043,7 +1037,7 @@ void uwsgi_destroy_request(struct wsgi_request *wsgi_req) {
// reset for avoiding following requests to fail on non-uwsgi protocols
// thanks Marko Tiikkaja for catching it
wsgi_req->uh->_pktsize = 0;
wsgi_req->uh->pktsize = 0;
// some plugins expected async_id to be defined before setup
int tmp_id = wsgi_req->async_id;
@@ -1127,13 +1121,13 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) {
}
// leave harakiri mode
if (uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].harakiri > 0) {
set_harakiri(wsgi_req, 0);
if (uwsgi.workers[uwsgi.mywid].harakiri > 0) {
set_harakiri(0);
}
// leave user harakiri mode
if (uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].user_harakiri > 0) {
set_user_harakiri(wsgi_req, 0);
if (uwsgi.workers[uwsgi.mywid].user_harakiri > 0) {
set_user_harakiri(0);
}
if (!wsgi_req->do_not_account) {
@@ -1191,7 +1185,7 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) {
// reset request
wsgi_req->uh->_pktsize = 0;
wsgi_req->uh->pktsize = 0;
tmp_id = wsgi_req->async_id;
memset(wsgi_req, 0, sizeof(struct wsgi_request));
// some plugins expected async_id to be defined before setup
@@ -1199,26 +1193,17 @@ void uwsgi_close_request(struct wsgi_request *wsgi_req) {
// yes, this is pretty useless but we cannot ensure all of the plugin have the same behaviour
uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].in_request = 0;
if (uwsgi.max_requests > 0 && uwsgi.workers[uwsgi.mywid].delta_requests >= (uwsgi.max_requests + ((uwsgi.mywid-1) * uwsgi.max_requests_delta))
if (uwsgi.max_requests > 0 && uwsgi.workers[uwsgi.mywid].delta_requests >= uwsgi.max_requests
&& (end_of_request - (uwsgi.workers[uwsgi.mywid].last_spawn * 1000000) >= uwsgi.min_worker_lifetime * 1000000)) {
goodbye_cruel_world("max requests reached (%llu >= %llu)",
(unsigned long long) uwsgi.workers[uwsgi.mywid].delta_requests,
(unsigned long long) (uwsgi.max_requests + ((uwsgi.mywid-1) * uwsgi.max_requests_delta))
);
goodbye_cruel_world();
}
if (uwsgi.reload_on_as && (rlim_t) vsz >= uwsgi.reload_on_as && (end_of_request - (uwsgi.workers[uwsgi.mywid].last_spawn * 1000000) >= uwsgi.min_worker_lifetime * 1000000)) {
goodbye_cruel_world("reload-on-as limit reached (%llu >= %llu)",
(unsigned long long) (rlim_t) vsz,
(unsigned long long) uwsgi.reload_on_as
);
goodbye_cruel_world();
}
if (uwsgi.reload_on_rss && (rlim_t) rss >= uwsgi.reload_on_rss && (end_of_request - (uwsgi.workers[uwsgi.mywid].last_spawn * 1000000) >= uwsgi.min_worker_lifetime * 1000000)) {
goodbye_cruel_world("reload-on-rss limit reached (%llu >= %llu)",
(unsigned long long) (rlim_t) rss,
(unsigned long long) uwsgi.reload_on_rss
);
goodbye_cruel_world();
}
@@ -1399,7 +1384,7 @@ int wsgi_req_async_recv(struct wsgi_request *wsgi_req) {
// enter harakiri mode
if (uwsgi.harakiri_options.workers > 0) {
set_harakiri(wsgi_req, uwsgi.harakiri_options.workers);
set_harakiri(uwsgi.harakiri_options.workers);
}
return 0;
@@ -1431,7 +1416,7 @@ int wsgi_req_recv(int queue, struct wsgi_request *wsgi_req) {
// enter harakiri mode
if (uwsgi.harakiri_options.workers > 0) {
set_harakiri(wsgi_req, uwsgi.harakiri_options.workers);
set_harakiri(uwsgi.harakiri_options.workers);
}
#ifdef UWSGI_ROUTING
@@ -1552,7 +1537,7 @@ int wsgi_req_accept(int queue, struct wsgi_request *wsgi_req) {
thunder_unlock;
uwsgi_receive_signal(wsgi_req, interesting_fd, "worker", uwsgi.mywid);
uwsgi_receive_signal(interesting_fd, "worker", uwsgi.mywid);
if (uwsgi.threads > 1)
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &ret);
@@ -1803,15 +1788,9 @@ void *uwsgi_malloc(size_t size) {
}
void *uwsgi_calloc(size_t size) {
// thanks Mathieu Dupuy for pointing out that calloc is faster
// than malloc + memset
char *ptr = calloc(1, size);
if (ptr == NULL) {
uwsgi_error("calloc()");
uwsgi_log("!!! tried memory allocation of %llu bytes !!!\n", (unsigned long long) size);
uwsgi_backtrace(uwsgi.backtrace_depth);
exit(1);
}
char *ptr = uwsgi_malloc(size);
memset(ptr, 0, size);
return ptr;
}
@@ -1853,7 +1832,7 @@ char *magic_sub(char *buffer, size_t len, size_t * size, char *magic_table[]) {
for (i = 0; i < len; i++) {
if (buffer[i] == '%' && (i + 1) < len && magic_table[(unsigned char) buffer[i + 1]]) {
old_magic_buf = magic_buf;
magic_buf = uwsgi_concat3n(old_magic_buf, magic_len, magic_table[(unsigned char) buffer[i + 1]], strlen(magic_table[(unsigned char) buffer[i + 1]]), buffer + i + 2, len - i - 2);
magic_buf = uwsgi_concat3n(old_magic_buf, magic_len, magic_table[(unsigned char) buffer[i + 1]], strlen(magic_table[(unsigned char) buffer[i + 1]]), buffer + i + 2, len - i);
free(old_magic_buf);
magic_len += strlen(magic_table[(unsigned char) buffer[i + 1]]);
magic_ptr = magic_buf + magic_len;
@@ -1883,6 +1862,24 @@ void init_magic_table(char *magic_table[]) {
magic_table['('] = "%(";
}
char *uwsgi_get_last_char(char *what, char c) {
size_t len = strlen(what);
while (len--) {
if (what[len] == c)
return what + len;
}
return NULL;
}
char *uwsgi_get_last_charn(char *what, size_t len, char c) {
while (len--) {
if (what[len] == c)
return what + len;
}
return NULL;
}
char *uwsgi_num2str(int num) {
char *str = uwsgi_malloc(11);
@@ -1914,7 +1911,13 @@ int uwsgi_long2str2n(unsigned long long num, char *ptr, int size) {
}
int is_unix(char *socket_name, int len) {
return !memchr(socket_name, ':', len);
int i;
for (i = 0; i < len; i++) {
if (socket_name[i] == ':')
return 0;
}
return 1;
}
int is_a_number(char *what) {
@@ -2213,19 +2216,6 @@ void uwsgi_dyn_dict_del(struct uwsgi_dyn_dict *item) {
free(item);
}
void uwsgi_dyn_dict_free(struct uwsgi_dyn_dict **dd) {
struct uwsgi_dyn_dict *attr = *dd;
while(attr) {
struct uwsgi_dyn_dict *tmp = attr;
attr = attr->next;
if (tmp->value) free(tmp->value);
free(tmp);
}
*dd = NULL;
}
void *uwsgi_malloc_shared(size_t size) {
void *addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
@@ -2241,12 +2231,6 @@ void *uwsgi_malloc_shared(size_t size) {
void *uwsgi_calloc_shared(size_t size) {
void *ptr = uwsgi_malloc_shared(size);
// NOTE by Mathieu Dupuy:
// OSes guarantee mmap MAP_ANON memory area to be zero-filled (see man pages)
// we should trust it, but history has taught us it is better to be paranoid.
// Lucky enough this function is called ony in startup phases, so performance
// tips/tricks are irrelevant (So, le'ts call memset...)
memset(ptr, 0, size);
return ptr;
}
@@ -3140,8 +3124,6 @@ pid_t uwsgi_fork(char *name) {
#if defined(__linux__) || defined(__sun__)
int i;
for (i = 0; i < uwsgi.argc; i++) {
// stop fixing original argv if the new one is bigger
if (!uwsgi.orig_argv[i]) break;
strcpy(uwsgi.orig_argv[i], uwsgi.argv[i]);
}
#endif
@@ -3532,7 +3514,7 @@ int uwsgi_tmpfd() {
tmpdir = "/tmp";
}
#ifdef O_TMPFILE
fd = open(tmpdir, O_TMPFILE | O_RDWR, S_IRUSR | S_IWUSR);
fd = open(tmpdir, O_TMPFILE | O_RDWR);
if (fd >= 0) {
return fd;
}
@@ -3614,13 +3596,6 @@ void uwsgi_write_pidfile(char *pidfile_name) {
}
}
void uwsgi_write_pidfile_explicit(char *pidfile_name, pid_t pid) {
uwsgi_log("writing pidfile to %s\n", pidfile_name);
if (uwsgi_write_intfile(pidfile_name, (int) pid)) {
uwsgi_log("could not write pidfile.\n");
}
}
char *uwsgi_expand_path(char *dir, int dir_len, char *ptr) {
char src[PATH_MAX + 1];
memcpy(src, dir, dir_len);
@@ -3901,6 +3876,7 @@ int uwsgi_kvlist_parse(char *src, size_t len, char list_separator, char kv_separ
}
}
va_end(ap);
base = ptr;
break;
}
else if (usl->value[i] == '\\' && !escaped) {
@@ -4470,7 +4446,6 @@ void uwsgi_setns(char *path) {
}
}
free(fds);
close(ns_fd);
break;
}
if (fds)
@@ -4504,29 +4479,6 @@ mode_t uwsgi_mode_t(char *value, int *error) {
return mode;
}
int uwsgi_wait_for_socket(char *socket_name) {
if (!uwsgi.wait_for_socket_timeout) {
uwsgi.wait_for_socket_timeout = 60;
}
uwsgi_log("waiting for %s (max %d seconds) ...\n", socket_name, uwsgi.wait_for_socket_timeout);
int counter = 0;
for (;;) {
if (counter > uwsgi.wait_for_socket_timeout) {
uwsgi_log("%s unavailable after %d seconds\n", socket_name, counter);
return -1;
}
// wait for 1 second to respect uwsgi.wait_for_fs_timeout
int fd = uwsgi_connect(socket_name, 1, 0);
if (fd < 0) goto retry;
close(fd);
uwsgi_log_verbose("%s ready\n", socket_name);
return 0;
retry:
sleep(1);
counter++;
}
return -1;
}
int uwsgi_wait_for_mountpoint(char *mountpoint) {
if (!uwsgi.wait_for_fs_timeout) {
@@ -4539,81 +4491,47 @@ int uwsgi_wait_for_mountpoint(char *mountpoint) {
uwsgi_log("%s unavailable after %d seconds\n", mountpoint, counter);
return -1;
}
struct stat st0;
struct stat st1;
if (stat(mountpoint, &st0)) goto retry;
if (!S_ISDIR(st0.st_mode)) goto retry;
char *relative = uwsgi_concat2(mountpoint, "/../");
if (stat(relative, &st1)) {
free(relative);
goto retry;
}
free(relative);
// useless :P
struct stat st0;
struct stat st1;
if (stat(mountpoint, &st0)) goto retry;
if (!S_ISDIR(st0.st_mode)) goto retry;
char *relative = uwsgi_concat2(mountpoint, "/../");
if (stat(relative, &st1)) {
free(relative);
goto retry;
}
free(relative);
// useless :P
if (!S_ISDIR(st1.st_mode)) goto retry;
if (st0.st_dev == st1.st_dev) goto retry;
if (st0.st_dev == st1.st_dev) goto retry;
uwsgi_log_verbose("%s mounted\n", mountpoint);
return 0;
retry:
sleep(1);
counter++;
}
return -1;
}
// type -> 1 file, 2 dir, 0 both
int uwsgi_wait_for_fs(char *filename, int type) {
if (!uwsgi.wait_for_fs_timeout) {
uwsgi.wait_for_fs_timeout = 60;
if (!uwsgi.wait_for_fs_timeout) {
uwsgi.wait_for_fs_timeout = 60;
}
uwsgi_log("waiting for %s (max %d seconds) ...\n", filename, uwsgi.wait_for_fs_timeout);
int counter = 0;
for (;;) {
if (counter > uwsgi.wait_for_fs_timeout) {
uwsgi_log("%s unavailable after %d seconds\n", filename, counter);
return -1;
if (counter > uwsgi.wait_for_fs_timeout) {
uwsgi_log("%s unavailable after %d seconds\n", filename, counter);
return -1;
}
struct stat st;
if (stat(filename, &st)) goto retry;
if (type == 1 && !S_ISREG(st.st_mode)) goto retry;
if (type == 2 && !S_ISDIR(st.st_mode)) goto retry;
struct stat st;
if (stat(filename, &st)) goto retry;
if (type == 1 && !S_ISREG(st.st_mode)) goto retry;
if (type == 2 && !S_ISDIR(st.st_mode)) goto retry;
uwsgi_log_verbose("%s found\n", filename);
return 0;
return 0;
retry:
sleep(1);
counter++;
}
return -1;
}
#if !defined(_GNU_SOURCE) && !defined(__UCLIBC__)
int uwsgi_versionsort(const struct dirent **da, const struct dirent **db) {
const char *a = (*da)->d_name;
const char *b = (*db)->d_name;
long la, lb;
char *endptr;
// Check if a and b are valid numbers.
la = strtol(a, &endptr, 10);
if (strcmp(endptr, "\0") || endptr == a) {
a = NULL;
}
lb = strtol(b, &endptr, 10);
if (strcmp(endptr, "\0") || endptr == b) {
b = NULL;
}
if (a && b) {
return (la < lb ? -1 : la > lb);
} else if (a) {
return -1;
} else if (b) {
return 1;
} else {
return strcmp((*da)->d_name, (*db)->d_name);
}
}
#endif
Executable → Regular
+27 -226
View File
@@ -2,7 +2,7 @@
*** uWSGI ***
Copyright (C) 2009-2015 Unbit S.a.s. <info@unbit.it>
Copyright (C) 2009-2014 Unbit S.a.s. <info@unbit.it>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
@@ -47,8 +47,6 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"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},
{"http11-socket", required_argument, 0, "bind to the specified UNIX/TCP socket using HTTP 1.1 (Keep-Alive) protocol", uwsgi_opt_add_socket, "http11", 0},
#ifdef UWSGI_SSL
{"https-socket", required_argument, 0, "bind to the specified UNIX/TCP socket using HTTPS protocol", uwsgi_opt_add_ssl_socket, "https", 0},
{"https-socket-modifier1", required_argument, 0, "force the specified modifier1 when using HTTPS protocol", uwsgi_opt_set_64bit, &uwsgi.https_modifier1, 0},
@@ -174,7 +172,7 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"listen", required_argument, 'l', "set the socket listen queue size", uwsgi_opt_set_int, &uwsgi.listen_queue, 0},
{"max-vars", required_argument, 'v', "set the amount of internal iovec/vars structures", uwsgi_opt_max_vars, NULL, 0},
{"max-apps", required_argument, 0, "set the maximum number of per-worker applications", uwsgi_opt_set_int, &uwsgi.max_apps, 0},
{"buffer-size", required_argument, 'b', "set internal buffer size", uwsgi_opt_set_64bit, &uwsgi.buffer_size, 0},
{"buffer-size", required_argument, 'b', "set internal buffer size", uwsgi_opt_set_16bit, &uwsgi.buffer_size, 0},
{"memory-report", no_argument, 'm', "enable memory report", uwsgi_opt_true, &uwsgi.logging_options.memory_report, 0},
{"profiler", required_argument, 0, "enable the specified profiler", uwsgi_opt_set_str, &uwsgi.profiler, 0},
{"cgi-mode", no_argument, 'c', "force CGI-mode for plugins supporting it", uwsgi_opt_true, &uwsgi.cgi_mode, 0},
@@ -204,8 +202,6 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"emperor", required_argument, 0, "run the Emperor", uwsgi_opt_add_string_list, &uwsgi.emperor, 0},
{"emperor-proxy-socket", required_argument, 0, "force the vassal to became an Emperor proxy", uwsgi_opt_set_str, &uwsgi.emperor_proxy, 0},
{"emperor-wrapper", required_argument, 0, "set a binary wrapper for vassals", uwsgi_opt_set_str, &uwsgi.emperor_wrapper, 0},
{"emperor-wrapper-override", required_argument, 0, "set a binary wrapper for vassals to try before the default one", uwsgi_opt_add_string_list, &uwsgi.emperor_wrapper_override, 0},
{"emperor-wrapper-fallback", required_argument, 0, "set a binary wrapper for vassals to try as a last resort", uwsgi_opt_add_string_list, &uwsgi.emperor_wrapper_fallback, 0},
{"emperor-nofollow", no_argument, 0, "do not follow symlinks when checking for mtime", uwsgi_opt_true, &uwsgi.emperor_nofollow, 0},
{"emperor-procname", required_argument, 0, "set the Emperor process name", uwsgi_opt_set_str, &uwsgi.emperor_procname, 0},
{"emperor-freq", required_argument, 0, "set the Emperor scan frequency (default 3 seconds)", uwsgi_opt_set_int, &uwsgi.emperor_freq, 0},
@@ -214,10 +210,8 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"emperor-pidfile", required_argument, 0, "write the Emperor pid in the specified file", uwsgi_opt_set_str, &uwsgi.emperor_pidfile, 0},
{"emperor-tyrant", no_argument, 0, "put the Emperor in Tyrant mode", uwsgi_opt_true, &uwsgi.emperor_tyrant, 0},
{"emperor-tyrant-nofollow", no_argument, 0, "do not follow symlinks when checking for uid/gid in Tyrant mode", uwsgi_opt_true, &uwsgi.emperor_tyrant_nofollow, 0},
{"emperor-tyrant-initgroups", no_argument, 0, "add additional groups set via initgroups() in Tyrant mode", uwsgi_opt_true, &uwsgi.emperor_tyrant_initgroups, 0},
{"emperor-stats", required_argument, 0, "run the Emperor stats server", uwsgi_opt_set_str, &uwsgi.emperor_stats, 0},
{"emperor-stats-server", required_argument, 0, "run the Emperor stats server", uwsgi_opt_set_str, &uwsgi.emperor_stats, 0},
{"emperor-trigger-socket", required_argument, 0, "enable the Emperor trigger socket", uwsgi_opt_set_str, &uwsgi.emperor_trigger_socket, 0},
{"early-emperor", no_argument, 0, "spawn the emperor as soon as possibile", uwsgi_opt_true, &uwsgi.early_emperor, 0},
{"emperor-broodlord", required_argument, 0, "run the emperor in BroodLord mode", uwsgi_opt_set_int, &uwsgi.emperor_broodlord, 0},
{"emperor-throttle", required_argument, 0, "set throttling level (in milliseconds) for bad behaving vassals (default 1000)", uwsgi_opt_set_int, &uwsgi.emperor_throttle, 0},
@@ -234,19 +228,11 @@ static struct uwsgi_option uwsgi_base_options[] = {
#if defined(__linux__) && !defined(OBSOLETE_LINUX_KERNEL)
{"emperor-use-clone", required_argument, 0, "use clone() instead of fork() passing the specified unshare() flags", uwsgi_opt_set_unshare, &uwsgi.emperor_clone, 0},
#endif
{"emperor-use-fork-server", required_argument, 0, "connect to the specified fork server instead of using plain fork() for new vassals", uwsgi_opt_set_str, &uwsgi.emperor_use_fork_server, 0},
{"vassal-fork-base", required_argument, 0, "use plain fork() for the specified vassal (instead of a fork-server)", uwsgi_opt_add_string_list, &uwsgi.vassal_fork_base, 0},
{"emperor-subreaper", no_argument, 0, "force the Emperor to be a sub-reaper (if supported)", uwsgi_opt_true, &uwsgi.emperor_subreaper, 0},
#ifdef UWSGI_CAP
{"emperor-cap", required_argument, 0, "set vassals capability", uwsgi_opt_set_emperor_cap, NULL, 0},
{"vassals-cap", required_argument, 0, "set vassals capability", uwsgi_opt_set_emperor_cap, NULL, 0},
{"vassal-cap", required_argument, 0, "set vassals capability", uwsgi_opt_set_emperor_cap, NULL, 0},
#endif
{"emperor-collect-attribute", required_argument, 0, "collect the specified vassal attribute from imperial monitors", uwsgi_opt_add_string_list, &uwsgi.emperor_collect_attributes, 0},
{"emperor-collect-attr", required_argument, 0, "collect the specified vassal attribute from imperial monitors", uwsgi_opt_add_string_list, &uwsgi.emperor_collect_attributes, 0},
{"emperor-fork-server-attr", required_argument, 0, "set teh vassal's attribute to get when checking for fork-server", uwsgi_opt_set_str, &uwsgi.emperor_fork_server_attr, 0},
{"emperor-wrapper-attr", required_argument, 0, "set the vassal's attribute to get when checking for fork-wrapper", uwsgi_opt_set_str, &uwsgi.emperor_wrapper_attr, 0},
{"emperor-chdir-attr", required_argument, 0, "set the vassal's attribute to get when checking for chdir", uwsgi_opt_set_str, &uwsgi.emperor_chdir_attr, 0},
{"imperial-monitor-list", no_argument, 0, "list enabled imperial monitors", uwsgi_opt_true, &uwsgi.imperial_monitor_list, 0},
{"imperial-monitors-list", no_argument, 0, "list enabled imperial monitors", uwsgi_opt_true, &uwsgi.imperial_monitor_list, 0},
{"vassals-inherit", required_argument, 0, "add config templates to vassals config (uses --inherit)", uwsgi_opt_add_string_list, &uwsgi.vassals_templates, 0},
@@ -262,13 +248,11 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"heartbeat", required_argument, 0, "announce healthiness to the emperor", uwsgi_opt_set_int, &uwsgi.heartbeat, 0},
{"zeus", required_argument, 0, "enable Zeus mode", uwsgi_opt_set_str, &uwsgi.zeus, 0},
{"reload-mercy", required_argument, 0, "set the maximum time (in seconds) we wait for workers and other processes to die during reload/shutdown", uwsgi_opt_set_int, &uwsgi.reload_mercy, 0},
{"worker-reload-mercy", required_argument, 0, "set the maximum time (in seconds) a worker can take to reload/shutdown (default is 60)", uwsgi_opt_set_int, &uwsgi.worker_reload_mercy, 0},
{"mule-reload-mercy", required_argument, 0, "set the maximum time (in seconds) a mule can take to reload/shutdown (default is 60)", uwsgi_opt_set_int, &uwsgi.mule_reload_mercy, 0},
{"exit-on-reload", no_argument, 0, "force exit even if a reload is requested", uwsgi_opt_true, &uwsgi.exit_on_reload, 0},
{"die-on-term", no_argument, 0, "exit instead of brutal reload on SIGTERM (no more needed)", uwsgi_opt_deprecated, &uwsgi.die_on_term, 0},
{"die-on-term", no_argument, 0, "exit instead of brutal reload on SIGTERM", uwsgi_opt_true, &uwsgi.die_on_term, 0},
{"force-gateway", no_argument, 0, "force the spawn of the first registered gateway without a master", uwsgi_opt_true, &uwsgi.force_gateway, 0},
{"help", no_argument, 'h', "show this help", uwsgi_help, NULL, UWSGI_OPT_IMMEDIATE},
{"usage", no_argument, 'h', "show this help", uwsgi_help, NULL, UWSGI_OPT_IMMEDIATE},
@@ -278,7 +262,6 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"reaper", no_argument, 'r', "call waitpid(-1,...) after each request to get rid of zombies", uwsgi_opt_true, &uwsgi.reaper, 0},
{"max-requests", required_argument, 'R', "reload workers after the specified amount of managed requests", uwsgi_opt_set_64bit, &uwsgi.max_requests, 0},
{"max-requests-delta", required_argument, 0, "add (worker_id * delta) to the max_requests value of each worker", uwsgi_opt_set_64bit, &uwsgi.max_requests_delta, 0},
{"min-worker-lifetime", required_argument, 0, "number of seconds worker must run before being reloaded (default is 60)", uwsgi_opt_set_64bit, &uwsgi.min_worker_lifetime, 0},
{"max-worker-lifetime", required_argument, 0, "reload workers after the specified amount of seconds (default is disabled)", uwsgi_opt_set_64bit, &uwsgi.max_worker_lifetime, 0},
@@ -326,11 +309,9 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"spooler-processes", required_argument, 0, "set the number of processes for spoolers", uwsgi_opt_set_int, &uwsgi.spooler_numproc, UWSGI_OPT_IMMEDIATE},
{"spooler-quiet", no_argument, 0, "do not be verbose with spooler tasks", uwsgi_opt_true, &uwsgi.spooler_quiet, 0},
{"spooler-max-tasks", required_argument, 0, "set the maximum number of tasks to run before recycling a spooler", uwsgi_opt_set_int, &uwsgi.spooler_max_tasks, 0},
{"spooler-signal-as-task", no_argument, 0, "treat signal events as tasks in spooler, combine used with spooler-max-tasks", uwsgi_opt_true, &uwsgi.spooler_signal_as_task, 0},
{"spooler-harakiri", required_argument, 0, "set harakiri timeout for spooler tasks", uwsgi_opt_set_int, &uwsgi.harakiri_options.spoolers, 0},
{"spooler-frequency", required_argument, 0, "set spooler frequency", uwsgi_opt_set_int, &uwsgi.spooler_frequency, 0},
{"spooler-freq", required_argument, 0, "set spooler frequency", uwsgi_opt_set_int, &uwsgi.spooler_frequency, 0},
{"spooler-cheap", no_argument, 0, "set spooler cheap mode", uwsgi_opt_true, &uwsgi.spooler_cheap, 0},
{"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},
@@ -359,8 +340,6 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"pidfile", required_argument, 0, "create pidfile (before privileges drop)", uwsgi_opt_set_str, &uwsgi.pidfile, 0},
{"pidfile2", required_argument, 0, "create pidfile (after privileges drop)", uwsgi_opt_set_str, &uwsgi.pidfile2, 0},
{"safe-pidfile", required_argument, 0, "create safe pidfile (before privileges drop)", uwsgi_opt_set_str, &uwsgi.safe_pidfile, 0},
{"safe-pidfile2", required_argument, 0, "create safe pidfile (after privileges drop)", uwsgi_opt_set_str, &uwsgi.safe_pidfile2, 0},
{"chroot", required_argument, 0, "chroot() to the specified directory", uwsgi_opt_set_str, &uwsgi.chroot, 0},
#ifdef __linux__
{"pivot-root", required_argument, 0, "pivot_root() to the specified directories (new_root and put_old must be separated with a space)", uwsgi_opt_set_str, &uwsgi.pivot_root, 0},
@@ -384,8 +363,6 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"setns-skip", required_argument, 0, "skip the specified entry when sending setns file descriptors", uwsgi_opt_add_string_list, &uwsgi.setns_socket_skip, 0},
{"setns", required_argument, 0, "join a namespace created by an external uWSGI instance", uwsgi_opt_set_str, &uwsgi.setns, 0},
{"setns-preopen", no_argument, 0, "open /proc/self/ns as soon as possible and cache fds", uwsgi_opt_true, &uwsgi.setns_preopen, 0},
{"fork-socket", required_argument, 0, "suspend the execution after early initialization and fork() at every unix socket connection", uwsgi_opt_set_str, &uwsgi.fork_socket, 0},
{"fork-server", required_argument, 0, "suspend the execution after early initialization and fork() at every unix socket connection", uwsgi_opt_set_str, &uwsgi.fork_socket, 0},
#endif
{"jailed", no_argument, 0, "mark the instance as jailed (force the execution of post_jail hooks)", uwsgi_opt_true, &uwsgi.jailed, 0},
#if defined(__FreeBSD__) || defined(__GNU_kFreeBSD__)
@@ -416,7 +393,7 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"hook-as-user-atexit", required_argument, 0, "run the specified hook before app exit and reload", uwsgi_opt_add_string_list, &uwsgi.hook_as_user_atexit, 0},
{"hook-pre-app", required_argument, 0, "run the specified hook before app loading", uwsgi_opt_add_string_list, &uwsgi.hook_pre_app, 0},
{"hook-post-app", required_argument, 0, "run the specified hook after app loading", uwsgi_opt_add_string_list, &uwsgi.hook_post_app, 0},
{"hook-post-fork", required_argument, 0, "run the specified hook after each fork", uwsgi_opt_add_string_list, &uwsgi.hook_post_fork, 0},
{"hook-post-fork", required_argument, 0, "run the specified hook after each fork", uwsgi_opt_add_string_list, &uwsgi.hook_post_fork, 0},
{"hook-accepting", required_argument, 0, "run the specified hook after each worker enter the accepting phase", uwsgi_opt_add_string_list, &uwsgi.hook_accepting, 0},
{"hook-accepting1", required_argument, 0, "run the specified hook after the first worker enters the accepting phase", uwsgi_opt_add_string_list, &uwsgi.hook_accepting1, 0},
{"hook-accepting-once", required_argument, 0, "run the specified hook after each worker enter the accepting phase (once per-instance)", uwsgi_opt_add_string_list, &uwsgi.hook_accepting_once, 0},
@@ -434,14 +411,6 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"hook-as-vassal", required_argument, 0, "run the specified hook before exec()ing the vassal", uwsgi_opt_add_string_list, &uwsgi.hook_as_vassal, 0},
{"hook-as-emperor", required_argument, 0, "run the specified hook in the emperor after the vassal has been started", uwsgi_opt_add_string_list, &uwsgi.hook_as_emperor, 0},
{"hook-as-on-demand-vassal", required_argument, 0, "run the specified hook whenever a vassal enters on-demand mode", uwsgi_opt_add_string_list, &uwsgi.hook_as_on_demand_vassal, 0},
{"hook-as-on-config-vassal", required_argument, 0, "run the specified hook whenever the emperor detects a config change for an on-demand vassal", uwsgi_opt_add_string_list, &uwsgi.hook_as_on_config_vassal, 0},
{"hook-as-emperor-before-vassal", required_argument, 0, "run the specified hook before the new vassal is spawned", uwsgi_opt_add_string_list, &uwsgi.hook_as_emperor_before_vassal, 0},
{"hook-as-vassal-before-drop", required_argument, 0, "run the specified hook into vassal, before dropping its privileges", uwsgi_opt_add_string_list, &uwsgi.hook_as_vassal_before_drop, 0},
{"hook-as-emperor-setns", required_argument, 0, "run the specified hook in the emperor entering vassal namespace", uwsgi_opt_add_string_list, &uwsgi.hook_as_emperor_setns, 0},
{"hook-as-mule", required_argument, 0, "run the specified hook in each mule", uwsgi_opt_add_string_list, &uwsgi.hook_as_mule, 0},
{"hook-as-gateway", required_argument, 0, "run the specified hook in each gateway", uwsgi_opt_add_string_list, &uwsgi.hook_as_gateway, 0},
@@ -498,9 +467,6 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"wait-for-mountpoint", required_argument, 0, "wait for the specified mountpoint to appear before running root hooks", uwsgi_opt_add_string_list, &uwsgi.wait_for_mountpoint, 0},
{"wait-for-fs-timeout", required_argument, 0, "set the timeout for wait-for-fs/file/dir", uwsgi_opt_set_int, &uwsgi.wait_for_fs_timeout, 0},
{"wait-for-socket", required_argument, 0, "wait for the specified socket to be ready before loading apps", uwsgi_opt_add_string_list, &uwsgi.wait_for_socket, 0},
{"wait-for-socket-timeout", required_argument, 0, "set the timeout for wait-for-socket", uwsgi_opt_set_int, &uwsgi.wait_for_socket_timeout, 0},
{"call-asap", required_argument, 0, "call the specified function as soon as possible", uwsgi_opt_add_string_list, &uwsgi.call_asap, 0},
{"call-pre-jail", required_argument, 0, "call the specified function before jailing", uwsgi_opt_add_string_list, &uwsgi.call_pre_jail, 0},
{"call-post-jail", required_argument, 0, "call the specified function after jailing", uwsgi_opt_add_string_list, &uwsgi.call_post_jail, 0},
@@ -550,7 +516,6 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"reload-on-rss", required_argument, 0, "reload if rss memory is higher than specified megabytes", uwsgi_opt_set_megabytes, &uwsgi.reload_on_rss, UWSGI_OPT_MEMORY},
{"evil-reload-on-as", required_argument, 0, "force the master to reload a worker if its address space is higher than specified megabytes", uwsgi_opt_set_megabytes, &uwsgi.evil_reload_on_as, UWSGI_OPT_MASTER | UWSGI_OPT_MEMORY},
{"evil-reload-on-rss", required_argument, 0, "force the master to reload a worker if its rss memory is higher than specified megabytes", uwsgi_opt_set_megabytes, &uwsgi.evil_reload_on_rss, UWSGI_OPT_MASTER | UWSGI_OPT_MEMORY},
{"mem-collector-freq", required_argument, 0, "set the memory collector frequency when evil reloads are in place", uwsgi_opt_set_int, &uwsgi.mem_collector_freq, 0},
{"reload-on-fd", required_argument, 0, "reload if the specified file descriptor is ready", uwsgi_opt_add_string_list, &uwsgi.reload_on_fd, UWSGI_OPT_MASTER},
{"brutal-reload-on-fd", required_argument, 0, "brutal reload if the specified file descriptor is ready", uwsgi_opt_add_string_list, &uwsgi.brutal_reload_on_fd, UWSGI_OPT_MASTER},
@@ -631,8 +596,6 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"notify-socket", required_argument, 0, "enable the notification socket", uwsgi_opt_set_str, &uwsgi.notify_socket, UWSGI_OPT_MASTER},
{"subscription-notify-socket", required_argument, 0, "set the notification socket for subscriptions", uwsgi_opt_set_str, &uwsgi.subscription_notify_socket, UWSGI_OPT_MASTER},
{"subscription-mountpoints", no_argument, 0, "enable mountpoints support for subscription system", uwsgi_opt_true, &uwsgi.subscription_mountpoints, UWSGI_OPT_MASTER},
{"subscription-mountpoint", no_argument, 0, "enable mountpoints support for subscription system", uwsgi_opt_true, &uwsgi.subscription_mountpoints, UWSGI_OPT_MASTER},
#ifdef UWSGI_SSL
{"legion", required_argument, 0, "became a member of a legion", uwsgi_opt_legion, NULL, UWSGI_OPT_MASTER},
@@ -699,7 +662,6 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"privileged-binary-patch-arg", required_argument, 0, "patch the uwsgi binary with a new command and arguments (before privileges drop)", uwsgi_opt_set_str, &uwsgi.privileged_binary_patch_arg, 0},
{"unprivileged-binary-patch-arg", required_argument, 0, "patch the uwsgi binary with a new command and arguments (after privileges drop)", uwsgi_opt_set_str, &uwsgi.unprivileged_binary_patch_arg, 0},
{"async", required_argument, 0, "enable async mode with specified cores", uwsgi_opt_set_int, &uwsgi.async, 0},
{"disable-async-warn-on-queue-full", no_argument, 0, "Disable printing 'async queue is full' warning messages.", uwsgi_opt_false, &uwsgi.async_warn_if_queue_full, 0},
{"max-fd", required_argument, 0, "set maximum number of file descriptors (requires root privileges)", uwsgi_opt_set_int, &uwsgi.requested_max_fd, 0},
{"logto", required_argument, 0, "set logfile/udp address", uwsgi_opt_set_str, &uwsgi.logfile, 0},
{"logto2", required_argument, 0, "log to specified file or udp address after privileges drop", uwsgi_opt_set_str, &uwsgi.logto2, 0},
@@ -714,8 +676,6 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"req-logger", required_argument, 0, "set/append a request logger", uwsgi_opt_set_req_logger, NULL, UWSGI_OPT_REQ_LOG_MASTER},
{"logger-req", required_argument, 0, "set/append a request logger", uwsgi_opt_set_req_logger, NULL, UWSGI_OPT_REQ_LOG_MASTER},
{"logger", required_argument, 0, "set/append a logger", uwsgi_opt_set_logger, NULL, UWSGI_OPT_MASTER | UWSGI_OPT_LOG_MASTER},
{"worker-logger", required_argument, 0, "set/append a logger in single-worker setup", uwsgi_opt_set_worker_logger, NULL, 0},
{"worker-logger-req", required_argument, 0, "set/append a request logger in single-worker setup", uwsgi_opt_set_req_logger, NULL, 0},
{"logger-list", no_argument, 0, "list enabled loggers", uwsgi_opt_true, &uwsgi.loggers_list, 0},
{"loggers-list", no_argument, 0, "list enabled loggers", uwsgi_opt_true, &uwsgi.loggers_list, 0},
{"threaded-logger", no_argument, 0, "offload log writing to a thread", uwsgi_opt_true, &uwsgi.threaded_logger, UWSGI_OPT_MASTER | UWSGI_OPT_LOG_MASTER},
@@ -723,9 +683,6 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"log-encoder", required_argument, 0, "add an item in the log encoder chain", uwsgi_opt_add_string_list, &uwsgi.requested_log_encoders, UWSGI_OPT_MASTER | UWSGI_OPT_LOG_MASTER},
{"log-req-encoder", required_argument, 0, "add an item in the log req encoder chain", uwsgi_opt_add_string_list, &uwsgi.requested_log_req_encoders, UWSGI_OPT_MASTER | UWSGI_OPT_LOG_MASTER},
{"worker-log-encoder", required_argument, 0, "add an item in the log encoder chain", uwsgi_opt_add_string_list, &uwsgi.requested_log_encoders, 0},
{"worker-log-req-encoder", required_argument, 0, "add an item in the log req encoder chain", uwsgi_opt_add_string_list, &uwsgi.requested_log_req_encoders, 0},
#ifdef UWSGI_PCRE
@@ -739,7 +696,7 @@ 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},
{"alarm-cheap", required_argument, 0, "use main alarm thread rather than create dedicated threads for curl-based alarms", uwsgi_opt_true, &uwsgi.alarm_cheap, 0},
{"alarm-freq", required_argument, 0, "tune the anti-loop alarm system (default 3 seconds)", uwsgi_opt_set_int, &uwsgi.alarm_freq, 0},
{"alarm-freq", required_argument, 0, "tune the anti-loop alam system (default 3 seconds)", uwsgi_opt_set_int, &uwsgi.alarm_freq, 0},
{"alarm-fd", required_argument, 0, "raise the specified alarm when an fd is read for read (by default it reads 1 byte, set 8 for eventfd)", uwsgi_opt_add_string_list, &uwsgi.alarm_fd_list, UWSGI_OPT_MASTER},
{"alarm-segfault", required_argument, 0, "raise the specified alarm when the segmentation fault handler is executed", uwsgi_opt_add_string_list, &uwsgi.alarm_segfault, UWSGI_OPT_MASTER},
{"segfault-alarm", required_argument, 0, "raise the specified alarm when the segmentation fault handler is executed", uwsgi_opt_add_string_list, &uwsgi.alarm_segfault, UWSGI_OPT_MASTER},
@@ -797,7 +754,6 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"cheaper-algo", required_argument, 0, "choose to algorithm used for adaptive process spawning", uwsgi_opt_set_str, &uwsgi.requested_cheaper_algo, UWSGI_OPT_MASTER},
{"cheaper-step", required_argument, 0, "number of additional processes to spawn at each overload", uwsgi_opt_set_int, &uwsgi.cheaper_step, UWSGI_OPT_MASTER | UWSGI_OPT_CHEAPER},
{"cheaper-overload", required_argument, 0, "increase workers after specified overload", uwsgi_opt_set_64bit, &uwsgi.cheaper_overload, UWSGI_OPT_MASTER | UWSGI_OPT_CHEAPER},
{"cheaper-idle", required_argument, 0, "decrease workers after specified idle (algo: spare2) (default: 10)", uwsgi_opt_set_int, &uwsgi.cheaper_idle, UWSGI_OPT_MASTER | UWSGI_OPT_CHEAPER},
{"cheaper-algo-list", no_argument, 0, "list enabled cheapers algorithms", uwsgi_opt_true, &uwsgi.cheaper_algo_list, 0},
{"cheaper-algos-list", no_argument, 0, "list enabled cheapers algorithms", uwsgi_opt_true, &uwsgi.cheaper_algo_list, 0},
{"cheaper-list", no_argument, 0, "list enabled cheapers algorithms", uwsgi_opt_true, &uwsgi.cheaper_algo_list, 0},
@@ -805,7 +761,6 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"cheaper-rss-limit-hard", required_argument, 0, "if total workers resident memory usage is higher try to stop workers", uwsgi_opt_set_64bit, &uwsgi.cheaper_rss_limit_hard, UWSGI_OPT_MASTER | UWSGI_OPT_CHEAPER},
{"idle", required_argument, 0, "set idle mode (put uWSGI in cheap mode after inactivity)", uwsgi_opt_set_int, &uwsgi.idle, UWSGI_OPT_MASTER},
{"die-on-idle", no_argument, 0, "shutdown uWSGI when idle", uwsgi_opt_true, &uwsgi.die_on_idle, 0},
{"die-on-no-workers", no_argument, 0, "shutdown uWSGI when no workers are running", uwsgi_opt_true, &uwsgi.die_on_no_workers, 0},
{"mount", required_argument, 0, "load application under mountpoint", uwsgi_opt_add_string_list, &uwsgi.mounts, 0},
{"worker-mount", required_argument, 0, "load application under mountpoint in the specified worker or after workers spawn", uwsgi_opt_add_string_list, &uwsgi.mounts, 0},
@@ -962,7 +917,6 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"close-on-exec2", no_argument, 0, "set close-on-exec on server sockets (could be required for spawning processes in requests)", uwsgi_opt_true, &uwsgi.close_on_exec2, 0},
{"mode", required_argument, 0, "set uWSGI custom mode", uwsgi_opt_set_str, &uwsgi.mode, 0},
{"env", required_argument, 0, "set environment variable", uwsgi_opt_set_env, NULL, 0},
{"ienv", required_argument, 0, "set environment variable (IMMEDIATE version)", uwsgi_opt_set_env, NULL, UWSGI_OPT_IMMEDIATE},
{"envdir", required_argument, 0, "load a daemontools compatible envdir", uwsgi_opt_add_string_list, &uwsgi.envdirs, 0},
{"early-envdir", required_argument, 0, "load a daemontools compatible envdir ASAP", uwsgi_opt_envdir, NULL, UWSGI_OPT_IMMEDIATE},
{"unenv", required_argument, 0, "unset environment variable", uwsgi_opt_unset_env, NULL, 0},
@@ -979,7 +933,7 @@ static struct uwsgi_option uwsgi_base_options[] = {
{"ns-net", required_argument, 0, "add network namespace", uwsgi_opt_set_str, &uwsgi.ns_net, 0},
#endif
{"enable-proxy-protocol", no_argument, 0, "enable PROXY1 protocol support (only for http parsers)", uwsgi_opt_true, &uwsgi.enable_proxy_protocol, 0},
{"reuse-port", no_argument, 0, "enable REUSE_PORT flag on socket (BSD and Linux >3.9 only)", uwsgi_opt_true, &uwsgi.reuse_port, 0},
{"reuse-port", no_argument, 0, "enable REUSE_PORT flag on socket (BSD only)", uwsgi_opt_true, &uwsgi.reuse_port, 0},
{"tcp-fast-open", required_argument, 0, "enable TCP_FASTOPEN flag on TCP sockets with the specified qlen value", uwsgi_opt_set_int, &uwsgi.tcp_fast_open, 0},
{"tcp-fastopen", required_argument, 0, "enable TCP_FASTOPEN flag on TCP sockets with the specified qlen value", uwsgi_opt_set_int, &uwsgi.tcp_fast_open, 0},
{"tcp-fast-open-client", no_argument, 0, "use sendto(..., MSG_FASTOPEN, ...) instead of connect() if supported", uwsgi_opt_true, &uwsgi.tcp_fast_open_client, 0},
@@ -1220,7 +1174,7 @@ void wait_for_threads() {
int sudden_death = 0;
pthread_mutex_lock(&uwsgi.six_feet_under_lock);
for (i = 1; i < uwsgi.threads; i++) {
for (i = 0; i < uwsgi.threads; i++) {
if (!pthread_equal(uwsgi.workers[uwsgi.mywid].cores[i].thread_id, pthread_self())) {
if (pthread_cancel(uwsgi.workers[uwsgi.mywid].cores[i].thread_id)) {
uwsgi_error("pthread_cancel()\n");
@@ -1233,7 +1187,7 @@ void wait_for_threads() {
goto end;
// wait for thread termination
for (i = 1; i < uwsgi.threads; i++) {
for (i = 0; i < uwsgi.threads; i++) {
if (!pthread_equal(uwsgi.workers[uwsgi.mywid].cores[i].thread_id, pthread_self())) {
ret = pthread_join(uwsgi.workers[uwsgi.mywid].cores[i].thread_id, NULL);
if (ret) {
@@ -1242,22 +1196,6 @@ void wait_for_threads() {
}
}
// cancel inital thread last since after pthread_cancel() and
// pthread_join() is called on it, the whole process will appear to be
// a zombie. although it won't eliminate process zombie time, but it
// should minimize it.
if (!pthread_equal(uwsgi.workers[uwsgi.mywid].cores[0].thread_id, pthread_self())) {
if (pthread_cancel(uwsgi.workers[uwsgi.mywid].cores[0].thread_id)) {
uwsgi_error("pthread_cancel() on initial thread\n");
goto end;
}
ret = pthread_join(uwsgi.workers[uwsgi.mywid].cores[0].thread_id, NULL);
if (ret) {
uwsgi_log("pthread_join() = %d on initial thread\n", ret);
}
}
end:
pthread_mutex_unlock(&uwsgi.six_feet_under_lock);
@@ -1279,7 +1217,7 @@ void gracefully_kill(int signum) {
}
// still not found a way to gracefully reload in async mode
if (uwsgi.async > 0) {
if (uwsgi.async > 1) {
exit(UWSGI_RELOAD_CODE);
}
@@ -1296,31 +1234,25 @@ void end_me(int signum) {
exit(UWSGI_END_CODE);
}
static void simple_goodbye_cruel_world(const char *reason) {
void simple_goodbye_cruel_world() {
if (uwsgi.threads > 1 && !uwsgi_instance_is_dying) {
wait_for_threads();
}
uwsgi.workers[uwsgi.mywid].manage_next_request = 0;
uwsgi_log("...The work of process %d is done (%s). Seeya!\n", getpid(), (reason != NULL ? reason : "no reason given"));
uwsgi_log("...The work of process %d is done. Seeya!\n", getpid());
exit(0);
}
void goodbye_cruel_world(const char *reason_fmt, ...) {
char reason[1024];
va_list args;
va_start(args, reason_fmt);
vsnprintf(reason, 1024, reason_fmt, args);
va_end(args);
void goodbye_cruel_world() {
uwsgi_curse(uwsgi.mywid, 0);
if (!uwsgi.gbcw_hook) {
simple_goodbye_cruel_world(reason);
simple_goodbye_cruel_world();
}
else {
uwsgi.gbcw_hook(reason);
uwsgi.gbcw_hook();
}
}
@@ -1531,7 +1463,7 @@ void what_i_am_doing() {
#else
ctime_r((const time_t *) &wsgi_req->start_of_request_in_sec, ctime_storage);
#endif
if (uwsgi.harakiri_options.workers > 0 && uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].harakiri < uwsgi_now()) {
if (uwsgi.harakiri_options.workers > 0 && uwsgi.workers[uwsgi.mywid].harakiri < uwsgi_now()) {
uwsgi_log("HARAKIRI: --- uWSGI worker %d core %d (pid: %d) WAS managing request %.*s since %.*s ---\n", (int) uwsgi.mywid, i, (int) uwsgi.mypid, wsgi_req->uri_len, wsgi_req->uri, 24, ctime_storage);
}
else {
@@ -1548,14 +1480,14 @@ void what_i_am_doing() {
#else
ctime_r((const time_t *) &wsgi_req->start_of_request_in_sec, ctime_storage);
#endif
if (uwsgi.harakiri_options.workers > 0 && uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].harakiri < uwsgi_now()) {
if (uwsgi.harakiri_options.workers > 0 && uwsgi.workers[uwsgi.mywid].harakiri < uwsgi_now()) {
uwsgi_log("HARAKIRI: --- uWSGI worker %d (pid: %d) WAS managing request %.*s since %.*s ---\n", (int) uwsgi.mywid, (int) uwsgi.mypid, wsgi_req->uri_len, wsgi_req->uri, 24, ctime_storage);
}
else {
uwsgi_log("SIGUSR2: --- uWSGI worker %d (pid: %d) is managing request %.*s since %.*s ---\n", (int) uwsgi.mywid, (int) uwsgi.mypid, wsgi_req->uri_len, wsgi_req->uri, 24, ctime_storage);
}
}
else if (uwsgi.harakiri_options.workers > 0 && uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].harakiri < uwsgi_now() && uwsgi.workers[uwsgi.mywid].sig) {
else if (uwsgi.harakiri_options.workers > 0 && uwsgi.workers[uwsgi.mywid].harakiri < uwsgi_now() && uwsgi.workers[uwsgi.mywid].sig) {
uwsgi_log("HARAKIRI: --- uWSGI worker %d (pid: %d) WAS handling signal %d ---\n", (int) uwsgi.mywid, (int) uwsgi.mypid, uwsgi.workers[uwsgi.mywid].signum);
}
}
@@ -1644,22 +1576,6 @@ static void vacuum(void) {
uwsgi_log("VACUUM: pidfile2 removed.\n");
}
}
if (uwsgi.safe_pidfile && !uwsgi.uid) {
if (unlink(uwsgi.safe_pidfile)) {
uwsgi_error("unlink()");
}
else {
uwsgi_log("VACUUM: safe pidfile removed.\n");
}
}
if (uwsgi.safe_pidfile2) {
if (unlink(uwsgi.safe_pidfile2)) {
uwsgi_error("unlink()");
}
else {
uwsgi_log("VACUUM: safe pidfile2 removed.\n");
}
}
if (uwsgi.chdir) {
if (chdir(uwsgi.chdir)) {
uwsgi_error("chdir()");
@@ -1695,18 +1611,6 @@ next:
}
}
}
if (uwsgi.master_fifo) {
// also remove all master fifo
struct uwsgi_string_list *usl;
uwsgi_foreach(usl, uwsgi.master_fifo) {
if (unlink(usl->value)) {
uwsgi_error("unlink()");
}
else {
uwsgi_log("VACUUM: master fifo %s removed.\n", usl->value);
}
}
}
}
}
}
@@ -1850,7 +1754,7 @@ void uwsgi_plugins_atexit(void) {
void uwsgi_backtrace(int depth) {
#if (defined(__GLIBC__) && !defined(__UCLIBC__))|| (defined(__APPLE__) && !defined(NO_EXECINFO)) || defined(UWSGI_HAS_EXECINFO)
#if defined(__linux__) || (defined(__APPLE__) && !defined(NO_EXECINFO)) || defined(UWSGI_HAS_EXECINFO)
#include <execinfo.h>
@@ -2088,7 +1992,6 @@ static char *uwsgi_at_file_read(char *filename) {
}
void uwsgi_setup(int argc, char *argv[], char *envp[]) {
#ifdef UWSGI_AS_SHARED_LIBRARY
#ifdef __APPLE__
char ***envPtr = _NSGetEnviron();
@@ -2098,6 +2001,7 @@ void uwsgi_setup(int argc, char *argv[], char *envp[]) {
int i;
struct utsname uuts;
// signal mask is inherited, and sme process manager could make a real mess...
sigset_t smask;
@@ -2268,8 +2172,6 @@ void uwsgi_setup(int argc, char *argv[], char *envp[]) {
struct group *gr = getgrgid(getgid());
uwsgi.magic_table['G'] = gr ? gr->gr_name : uwsgi.magic_table['g'];
configure:
// you can embed a ini file in the uWSGi binary with default options
#ifdef UWSGI_EMBED_CONFIG
uwsgi_ini_config("", uwsgi.magic_table);
@@ -2294,14 +2196,6 @@ configure:
// ok, the options dictionary is available, lets manage it
uwsgi_configure();
// stop the execution until a connection arrives on the fork socket
if (uwsgi.fork_socket) {
uwsgi_log_verbose("waiting for fork-socket connections...\n");
uwsgi_fork_server(uwsgi.fork_socket);
// if we are here a new process has been spawned
goto configure;
}
// fixup cwd
if (uwsgi.force_cwd) uwsgi.cwd = uwsgi.force_cwd;
@@ -2370,13 +2264,6 @@ configure:
// setup master logging
if (uwsgi.log_master)
uwsgi_setup_log_master();
else if (uwsgi.numproc == 1 && uwsgi.log_worker && uwsgi.master_process == 0) {
// hack for allowing request loggers
if (uwsgi.requested_req_logger)
uwsgi.req_log_master = 1;
uwsgi_setup_log_master();
uwsgi_threaded_logger_worker_spawn();
}
// setup offload engines
uwsgi_offload_engines_register_all();
@@ -2387,7 +2274,6 @@ configure:
// setup cheaper algos
uwsgi_register_cheaper_algo("spare", uwsgi_cheaper_algo_spare);
uwsgi_register_cheaper_algo("spare2", uwsgi_cheaper_algo_spare2);
uwsgi_register_cheaper_algo("backlog", uwsgi_cheaper_algo_backlog);
uwsgi_register_cheaper_algo("manual", uwsgi_cheaper_algo_manual);
@@ -2459,10 +2345,6 @@ configure:
uwsgi_log_initial("compiled with version: %s on %s\n", __VERSION__, UWSGI_BUILD_DATE);
#ifdef __RUMP__
uwsgi_log_initial("Rump system detected\n");
#else
struct utsname uuts;
#ifdef __sun__
if (uname(&uuts) < 0) {
#else
@@ -2475,7 +2357,6 @@ configure:
uwsgi_log_initial("nodename: %s\n", uuts.nodename);
uwsgi_log_initial("machine: %s\n", uuts.machine);
}
#endif
uwsgi_log_initial("clock source: %s\n", uwsgi.clock->name);
#ifdef UWSGI_PCRE
@@ -2603,10 +2484,6 @@ configure:
#if defined(__linux__) && !defined(__ia64__)
}
#endif
if (uwsgi.safe_pidfile && !uwsgi.is_a_reload) {
uwsgi_write_pidfile_explicit(uwsgi.safe_pidfile, masterpid);
}
}
@@ -2665,11 +2542,6 @@ int uwsgi_start(void *v_argv) {
uwsgi_as_root();
}
// wait for socket
uwsgi_foreach(usl, uwsgi.wait_for_socket) {
if (uwsgi_wait_for_socket(usl->value)) exit(1);
}
if (uwsgi.logto2) {
if (!uwsgi.is_a_reload || uwsgi.log_reopen) {
logto(uwsgi.logto2);
@@ -2688,13 +2560,10 @@ int uwsgi_start(void *v_argv) {
uwsgi_write_pidfile(uwsgi.pidfile2);
}
#ifndef __RUMP__
if (!uwsgi.master_process && !uwsgi.command_mode) {
uwsgi_log_initial("*** WARNING: you are running uWSGI without its master process manager ***\n");
}
#endif
#ifndef __RUMP__
#ifdef RLIMIT_NPROC
if (uwsgi.rl_nproc.rlim_max > 0) {
uwsgi.rl_nproc.rlim_cur = uwsgi.rl_nproc.rlim_max;
@@ -2714,8 +2583,6 @@ int uwsgi_start(void *v_argv) {
}
}
#endif
#endif
#ifndef __OpenBSD__
if (uwsgi.rl.rlim_max > 0) {
@@ -2794,7 +2661,7 @@ int uwsgi_start(void *v_argv) {
}
}
if (uwsgi.async > 0) {
if (uwsgi.async > 1) {
if ((unsigned long) uwsgi.max_fd < (unsigned long) uwsgi.async) {
uwsgi_log_initial("- your current max open files limit is %lu, this is lower than requested async cores !!! -\n", (unsigned long) uwsgi.max_fd);
uwsgi.rl.rlim_cur = uwsgi.async;
@@ -3048,23 +2915,8 @@ unsafe:
uwsgi_log("your server socket listen backlog is limited to %d connections\n", uwsgi.listen_queue);
#endif
uwsgi_log("your mercy for graceful operations on workers is %d seconds\n", uwsgi.worker_reload_mercy);
uwsgi_log("your request buffer size is %llu bytes\n", (unsigned long long) uwsgi.buffer_size);
if (!uwsgi.__buffer_size) {
if (uwsgi.buffer_size > 0xffff) {
uwsgi_log("your request buffer size for old plugins has been limited to 64k\n");
uwsgi.__buffer_size = 0xffff;
}
else {
uwsgi.__buffer_size = uwsgi.buffer_size;
}
}
else {
uwsgi_log("your request buffer size for old plugins is %u bytes\n", uwsgi.__buffer_size);
}
if (uwsgi.crons) {
struct uwsgi_cron *ucron = uwsgi.crons;
while (ucron) {
@@ -3117,7 +2969,7 @@ unsafe:
uwsgi_log("*** Operational MODE: threaded ***\n");
}
}
else if (uwsgi.async > 0) {
else if (uwsgi.async > 1) {
if (uwsgi.numproc > 1) {
uwsgi_log("*** Operational MODE: preforking+async ***\n");
}
@@ -3297,8 +3149,6 @@ next:
while (uspool) {
if (uspool->mode == UWSGI_SPOOLER_EXTERNAL)
goto next2;
// skip spooler start on cheap mode
if (uwsgi.spooler_cheap) goto next2;
uspool->pid = spooler_start(uspool);
next2:
uspool = uspool->next;
@@ -3354,33 +3204,12 @@ next2:
}
}
if (uwsgi.safe_pidfile2 && !uwsgi.is_a_reload) {
uwsgi_write_pidfile_explicit(uwsgi.safe_pidfile2, masterpid);
}
// END OF INITIALIZATION
return 0;
}
// this lives in a worker thread and periodically scans for memory usage
// when evil reloaders are in place
void *mem_collector(void *foobar) {
// block all signals
sigset_t smask;
sigfillset(&smask);
pthread_sigmask(SIG_BLOCK, &smask, NULL);
uwsgi_log_verbose("mem-collector thread started for worker %d\n", uwsgi.mywid);
for(;;) {
sleep(uwsgi.mem_collector_freq);
uint64_t rss = 0, vsz = 0;
get_memusage(&rss, &vsz);
uwsgi.workers[uwsgi.mywid].rss_size = rss;
uwsgi.workers[uwsgi.mywid].vsz_size = vsz;
}
return NULL;
}
int uwsgi_run() {
// !!! from now on, we could be in the master or in a worker !!!
@@ -3407,11 +3236,6 @@ int uwsgi_run() {
}
#endif
if (uwsgi.evil_reload_on_rss || uwsgi.evil_reload_on_as) {
pthread_t t;
pthread_create(&t, NULL, mem_collector, NULL);
}
// eventually maps (or disable) sockets for the worker
uwsgi_map_sockets();
@@ -3515,7 +3339,7 @@ void uwsgi_worker_run() {
// some apps could be mounted only on specific workers
uwsgi_init_worker_mount_apps();
if (uwsgi.async > 0) {
if (uwsgi.async > 1) {
// a stack of unused cores
uwsgi.async_queue_unused = uwsgi_malloc(sizeof(struct wsgi_request *) * uwsgi.async);
@@ -3659,7 +3483,7 @@ void uwsgi_ignition() {
uwsgi_log("your loop engine died. R.I.P.\n");
}
else {
if (uwsgi.async < 1) {
if (uwsgi.async < 2) {
simple_loop();
}
else {
@@ -3890,8 +3714,8 @@ void uwsgi_init_all_apps() {
what++;
for (j = 0; j < 256; j++) {
if (uwsgi.p[j]->mount_app) {
uwsgi_log("mounting %s on %s\n", what, app_mps->value[0] == 0 ? "/" : app_mps->value);
if (uwsgi.p[j]->mount_app(app_mps->value[0] == 0 ? "/" : app_mps->value, what) != -1)
uwsgi_log("mounting %s on %s\n", what, app_mps->value);
if (uwsgi.p[j]->mount_app(app_mps->value, what) != -1)
break;
}
}
@@ -4150,11 +3974,6 @@ void uwsgi_opt_set_16bit(char *opt, char *value, void *key) {
void uwsgi_opt_set_megabytes(char *opt, char *value, void *key) {
uint64_t *ptr = (uint64_t *) key;
if(strchr(value, '.') != NULL) {
double megabytes = atof(value);
*ptr = (uint64_t)(megabytes * 1024 * 1024);
return;
}
*ptr = (uint64_t)strtoul(value, NULL, 10) * 1024 * 1024;
}
@@ -4186,11 +4005,6 @@ void uwsgi_opt_set_logger(char *opt, char *value, void *prefix) {
}
}
void uwsgi_opt_set_worker_logger(char *opt, char *value, void *prefix) {
uwsgi_opt_set_logger(opt, value, prefix);
uwsgi.log_worker = 1;
}
void uwsgi_opt_set_req_logger(char *opt, char *value, void *prefix) {
if (!value)
@@ -4599,7 +4413,6 @@ int uwsgi_zerg_attach(char *value) {
if (zerg == NULL) {
uwsgi_log("--- invalid data received from zerg-server ---\n");
close(zerg_fd);
return -1;
}
@@ -4895,7 +4708,7 @@ extern char *uwsgi_dot_h;
char *uwsgi_get_dot_h() {
char *src = uwsgi_dot_h;
size_t len = strlen(src);
char *ptr = uwsgi_malloc((len / 2) + 1);
char *ptr = uwsgi_malloc(len / 2);
char *base = ptr;
size_t i;
unsigned int u;
@@ -4916,9 +4729,6 @@ char *uwsgi_get_dot_h() {
base = ub->buf;
ub->buf = NULL;
uwsgi_buffer_destroy(ub);
#else
// add final null byte
*ptr = '\0';
#endif
return base;
}
@@ -4931,7 +4741,7 @@ extern char *uwsgi_config_py;
char *uwsgi_get_config_py() {
char *src = uwsgi_config_py;
size_t len = strlen(src);
char *ptr = uwsgi_malloc((len / 2) + 1);
char *ptr = uwsgi_malloc(len / 2);
char *base = ptr;
size_t i;
unsigned int u;
@@ -4952,9 +4762,6 @@ char *uwsgi_get_config_py() {
base = ub->buf;
ub->buf = NULL;
uwsgi_buffer_destroy(ub);
#else
// add final null byte
*ptr = '\0';
#endif
return base;
}
@@ -5032,12 +4839,6 @@ void uwsgi_update_pidfiles() {
if (uwsgi.pidfile2) {
uwsgi_write_pidfile(uwsgi.pidfile2);
}
if (uwsgi.safe_pidfile) {
uwsgi_write_pidfile(uwsgi.safe_pidfile);
}
if (uwsgi.safe_pidfile2) {
uwsgi_write_pidfile(uwsgi.safe_pidfile2);
}
}
void uwsgi_opt_binary_append_data(char *opt, char *value, void *none) {
-110
View File
@@ -1,110 +0,0 @@
#include <uwsgi.h>
extern struct uwsgi_server uwsgi;
/*
The following functions are useful to implement simil-webdav support in plugins.
Most of them are not fully webdav compliant, but will work on the vast majority of clients.
*/
// a multi-status response (207) will return an xml with a list
// of <D:response> stanzas
struct uwsgi_buffer *uwsgi_webdav_multistatus_new() {
struct uwsgi_buffer *ub = uwsgi_buffer_new(uwsgi.page_size);
if (uwsgi_buffer_append(ub, "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n", 40)) goto error;
if (uwsgi_buffer_append(ub, "<D:multistatus xmlns:D=\"DAV:\">\n", 31)) goto error;
return ub;
error:
uwsgi_buffer_destroy(ub);
return NULL;
}
int uwsgi_webdav_multistatus_close(struct uwsgi_buffer *ub) {
if (uwsgi_buffer_append(ub, "</D:multistatus>\n", 17)) return -1;
return 0;
}
int uwsgi_webdav_multistatus_response_new(struct uwsgi_buffer *ub) {
if (uwsgi_buffer_append(ub, "<D:response>\n", 13)) return -1;
return 0;
}
int uwsgi_webdav_multistatus_response_close(struct uwsgi_buffer *ub) {
if (uwsgi_buffer_append(ub, "</D:response>\n", 14)) return -1;
return 0;
}
int uwsgi_webdav_multistatus_propstat_new(struct uwsgi_buffer *ub) {
if (uwsgi_buffer_append(ub, "<D:propstat>\n", 13)) return -1;
return 0;
}
int uwsgi_webdav_multistatus_propstat_close(struct uwsgi_buffer *ub) {
if (uwsgi_buffer_append(ub, "</D:propstat>\n", 14)) return -1;
return 0;
}
int uwsgi_webdav_multistatus_prop_new(struct uwsgi_buffer *ub) {
if (uwsgi_buffer_append(ub, "<D:prop>\n", 9)) return -1;
return 0;
}
int uwsgi_webdav_multistatus_prop_close(struct uwsgi_buffer *ub) {
if (uwsgi_buffer_append(ub, "</D:prop>\n", 10)) return -1;
return 0;
}
// shortcut for adding a propfind-response item
int uwsgi_webdav_propfind_item_add(struct uwsgi_buffer *ub, char *href, uint16_t href_len, uint64_t cl, time_t mtime, char *ctype, uint16_t ctype_len, char *displayname, uint16_t displayname_len, char *etag, uint16_t etag_len) {
if (uwsgi_webdav_multistatus_response_new(ub)) return -1;
if (uwsgi_buffer_append(ub, "<D:href>", 8)) return -1;
if (uwsgi_buffer_append(ub, href, href_len)) return -1;
if (uwsgi_buffer_append(ub, "</D:href>\n", 10)) return -1;
if (uwsgi_webdav_multistatus_propstat_new(ub)) return -1;
if (uwsgi_webdav_multistatus_prop_new(ub)) return -1;
if (href[href_len-1] == '/') {
if (uwsgi_buffer_append(ub, "<D:resourcetype><D:collection/></D:resourcetype>\n", 49)) return -1;
}
else {
// getcontentlength
if (uwsgi_buffer_append(ub, "<D:getcontentlength>", 20)) return -1;
if (uwsgi_buffer_num64(ub, cl)) return -1;
if (uwsgi_buffer_append(ub, "</D:getcontentlength>\n", 22)) return -1;
}
// getlastmodified
if (mtime > 0) {
if (uwsgi_buffer_append(ub, "<D:getlastmodified>", 19)) return -1;
if (uwsgi_buffer_httpdate(ub, mtime)) return -1;
if (uwsgi_buffer_append(ub, "</D:getlastmodified>\n", 21)) return -1;
}
// displayname
if (displayname_len > 0) {
if (uwsgi_buffer_append(ub, "<D:displayname>\n", 16)) return -1;
if (uwsgi_buffer_append_xml(ub, displayname, displayname_len)) return -1;
if (uwsgi_buffer_append(ub, "</D:displayname>\n", 17)) return -1;
}
if (ctype_len > 0) {
if (uwsgi_buffer_append(ub, "<D:getcontenttype>", 18)) return -1;
if (uwsgi_buffer_append(ub, ctype, ctype_len)) return -1;
if (uwsgi_buffer_append(ub, "</D:getcontenttype>\n", 20)) return -1;
}
if (etag_len > 0) {
if (uwsgi_buffer_append(ub, "<D:getetag>\n", 12)) return -1;
if (uwsgi_buffer_append_xml(ub, etag, etag_len)) return -1;
if (uwsgi_buffer_append(ub, "</D:getetag>\n", 13)) return -1;
}
if (uwsgi_webdav_multistatus_prop_close(ub)) return -1;
if (uwsgi_webdav_multistatus_propstat_close(ub)) return -1;
if (uwsgi_webdav_multistatus_response_close(ub)) return -1;
return 0;
}
+3 -25
View File
@@ -1,5 +1,3 @@
#include <uwsgi.h>
/*
*** WORK IN PROGRESS ***
@@ -18,11 +16,11 @@
# unencrypted mode
uwsgi --zeus 192.168.173.17:4040 --emperor /etc/uwsgi/vassals
uwsgi --zeus "192.168.173.17:4040 /etc/uwsgi/vassals"
# crypted mode
uwsgi --zeus 192.168.173.17:4040,foobar.crt,foobar.key --emperor /etc/uwsgi/vassals
uwsgi --zeus "192.168.173.17:4040,foobar.crt,foobar.key /etc/uwsgi/vassals"
# crypted + authentication mode
uwsgi --zeus 192.168.173.17:4040,foobar.crt,foobar.key,clients.pem --emperor /etc/uwsgi/vassals
uwsgi --zeus "192.168.173.17:4040,foobar.crt,foobar.key,clients.pem /etc/uwsgi/vassals"
to connect an Emperor to Zeus
@@ -66,23 +64,3 @@
11 -> VASSAL_DESTROYED {name: 'foobar.ini'} [the choosen emperor -> zeus]
*/
/*
check how many nodes the instace needs (default 1)
*/
int uwsgi_zeus_spawn_instance(struct uwsgi_instance *ui) {
int i, nodes = 1;
char *how_many_nodes = vassal_attr_get(ui, "zeus-nodes");
if (how_many_nodes) {
nodes = atoi(how_many_nodes);
}
for(i=0;i<nodes;i++) {
// now start analyzing nodes, the one with most
// free slots will be used
// send NEW_VASSAL request to the node,
// if it answers with ACCEPTED_VASSAL
}
return 0;
}
-2
View File
@@ -2,12 +2,10 @@ from flask import Flask, request
app = Flask(__name__)
app.debug = True
@app.route('/')
def hello_world():
return "<form method='POST' enctype='multipart/form-data' action='/upload'><input type='text' name='pippo'/><input type='file' name='ufile'/><input type='submit' value='upload'/></form>"
@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
return str(len(request.form.get('pippo', 'boh'))) + request.form.get('pippo', 'boh')
+1 -7
View File
@@ -3,18 +3,12 @@ import werkzeug.testapp
uwsgi.cache_set("/cache/get", "HTTP 1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<h1>I am the uWSGI cache</h1>")
def app001(env, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
return "PATH_INFO=%s" % env['PATH_INFO']
def app002(env, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
return "requests: %d" % uwsgi.total_requests()
uwsgi.applications = {
'': werkzeug.testapp.test_app,
'/app001': app001,
'/app002': app002
}
uwsgi.applications = { '':werkzeug.testapp.test_app, '/app001':app001, '/app002':app002 }
+18 -16
View File
@@ -1,23 +1,25 @@
import uwsgi
import os
def application(env, start_response):
boundary = 'uwsgi_mjpeg_frame'
boundary = 'uwsgi_mjpeg_frame'
start_response('200 Ok', [
('Cache-Control', 'no-cache'),
('Cache-Control', 'private'),
('Pragma', 'no-cache'),
('Content-Type', 'multipart/x-mixed-replace; boundary=' + boundary),
])
start_response('200 Ok', [
yield "--%s\r\n" % boundary
('Cache-Control', 'no-cache'),
('Cache-Control', 'private'),
('Pragma', 'no-cache'),
('Content-Type', 'multipart/x-mixed-replace; boundary=' + boundary),
]
)
while 1:
yield "Content-Type: image/jpeg\r\n\r\n"
print os.system('screencapture -t jpg -m -T 1 screenshot.jpg')
f = open('screenshot.jpg')
yield env['wsgi.file_wrapper'](f)
yield "\r\n--%s\r\n" % boundary
# os.system('./isightcapture -w 640 -h 480 screenshot.jpg')
yield "--%s\r\n" % boundary
while 1:
yield "Content-Type: image/jpeg\r\n\r\n"
print os.system('screencapture -t jpg -m -T 1 screenshot.jpg')
f = open('screenshot.jpg')
yield env['wsgi.file_wrapper'](f)
yield "\r\n--%s\r\n" % boundary
#os.system('./isightcapture -w 640 -h 480 screenshot.jpg')
+7 -15
View File
@@ -1,30 +1,22 @@
import werkzeug
import uwsgi
def zero_app(e, s):
s('200 OK', [('Content-Type', 'text/plain')])
def zero_app(e,s):
s('200 OK', [ ('Content-Type', 'text/plain') ])
return "0"
def not_found(e, s):
s('404 Not Found', [('Content-Type', 'text/plain')])
def not_found(e,s):
s('404 Not Found', [ ('Content-Type', 'text/plain') ])
return ""
def wsgi_app(e, s):
s('200 OK', [('Content-Type', 'text/plain')])
s('200 OK', [ ('Content-Type', 'text/plain') ])
yield "I am a WSGI app\n"
def internal_server_error(e, s):
s('500 Internal Server Error', [('Content-Type', 'text/plain')])
s('500 Internal Server Error', [ ('Content-Type', 'text/plain') ])
return ""
uwsgi.applications = {
'/wsgi': wsgi_app,
'/test': werkzeug.test_app,
'/zero': zero_app,
'/notfound': not_found,
'/ise': internal_server_error
}
uwsgi.applications = {'/wsgi':wsgi_app, '/test':werkzeug.test_app, '/zero':zero_app, '/notfound':not_found, '/ise':internal_server_error}
+4 -4
View File
@@ -3,11 +3,9 @@ import os
print("!!! uWSGI version:", uwsgi.version)
def ciao():
print("modifica su /tmp")
def ciao2():
print("nuovo uwsgi_server")
print os.getpid()
@@ -25,15 +23,17 @@ counter = 0
uwsgi.post_fork_hook = ciao2
def application(env, start_response):
global counter
#print(env)
start_response('200 Ok', [('Content-type', 'text/plain')])
yield "hello world"
yield "hello world2"
for i in range(1, 1000):
for i in range(1,1000):
yield str(i)
yield "\n"
+3 -3
View File
@@ -1,9 +1,9 @@
def mygen(uri):
for i in xrange(1, 100):
for i in xrange(1,100):
yield "ciao %s<br/>" % uri
def application(env, start_response=None):
def application(env, start_response = None):
return '200 OK', [('Content-Type', 'text/html')], "<h1>This is the fastest homepage of the world !!!</h1>"
# return '200 OK', [('Content-Type', 'text/html')], mygen(env['PATH_INFO'])
#return '200 OK', [('Content-Type', 'text/html')], mygen(env['PATH_INFO'])
+1 -2
View File
@@ -1,7 +1,6 @@
import uwsgi
def print_logs(ip, port, message):
print(ip, port, message)
print(ip, port, message)
uwsgi.udp_callable = print_logs
+2 -3
View File
@@ -4,11 +4,10 @@ from os import path
uwsgi.snmp_set_counter64(1, 0) # Number of requests
uwsgi.snmp_set_counter64(2, 0) # Number of bytes
def application(environ, start_response):
size = path.getsize('logo_uWSGI.png')
start_response('200 OK', [('Content-Type', 'image/png'), ('Content-Length', str(size))])
fd = open('logo_uWSGI.png', 'r')
start_response('200 OK', [('Content-Type', 'image/png'), ('Content-Length', str(size))] )
fd = open('logo_uWSGI.png','r')
uwsgi.snmp_incr_counter64(1)
uwsgi.snmp_incr_counter64(2, size)
return environ['wsgi.file_wrapper'](fd, 4096)
+4 -5
View File
@@ -4,24 +4,22 @@ import uwsgi
CONSUMERS = 4
def consumer(q):
while True:
item = q.get()
print(item)
# ... DO A HEAVY TASK HERE ...
#... DO A HEAVY TASK HERE ...
q.task_done()
def spawn_consumers():
global q
q = Queue.Queue()
for i in range(CONSUMERS):
t = Thread(target=consumer, args=(q,))
t = Thread(target=consumer,args=(q,))
t.daemon = True
t.start()
print("consumer %d on worker %d started" % (i, uwsgi.worker_id()))
uwsgi.post_fork_hook = spawn_consumers
@@ -35,3 +33,4 @@ def application(env, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
yield "Task enqueued"
+62 -60
View File
@@ -1,76 +1,78 @@
import uwsgi
def application(env, start_response):
# open the socket
fd = uwsgi.async_connect("192.168.173.100:3032")
# open the socket
fd = uwsgi.async_connect("192.168.173.100:3032")
# wait for connection ready (3s timeout)
yield uwsgi.wait_fd_write(fd, 3)
# wait for connection ready (3s timeout)
yield uwsgi.wait_fd_write(fd, 3)
# has timed out ?
if env['x-wsgiorg.fdevent.timeout']:
print "connection timed out !!!"
uwsgi.close(fd)
raise StopIteration
# has timed out ?
if env['x-wsgiorg.fdevent.timeout']:
print "connection timed out !!!"
uwsgi.close(fd)
raise StopIteration
# connection refused ?
if not uwsgi.is_connected(fd):
print "unable to connect"
uwsgi.close(fd)
raise StopIteration
# connection refused ?
if not uwsgi.is_connected(fd):
print "unable to connect"
uwsgi.close(fd)
raise StopIteration
# send request
# env can contains python objects, but send_message will discard them.
# In this way we will automagically have a congruent and valid uwsgi packet
uwsgi.async_send_message(fd, 0, 0, env)
# send request
# env can contains python objects, but send_message will discard them.
# In this way we will automagically have a congruent and valid uwsgi packet
uwsgi.async_send_message(fd, 0, 0, env)
# send the http body
# ready body in async mode and resend to fd
# uwsgi.recv will use always an internal buffer of 4096, but can be limited in the number of bytes to read
# send the http body
# ready body in async mode and resend to fd
# uwsgi.recv will use always an internal buffer of 4096, but can be limited in the number of bytes to read
# does this request has a body ?
cl = uwsgi.cl()
# does this request has a body ?
cl = uwsgi.cl()
if cl > 0:
# get the input fd
input = env['wsgi.input'].fileno()
if cl > 0:
# get the input fd
input = env['wsgi.input'].fileno()
# read (in async mode) upto 'cl' data and send to uwsgi peer
while cl > 0:
bufsize = min(cl, 4096)
yield uwsgi.wait_fd_read(input, 30)
if env['x-wsgiorg.fdevent.timeout']:
print "connection timed out !!!"
uwsgi.close(fd)
raise StopIteration
body = uwsgi.recv(input, bufsize)
if body:
uwsgi.send(fd, body)
cl = cl - len(body)
else:
break
# read (in async mode) upto 'cl' data and send to uwsgi peer
while cl > 0:
bufsize = min(cl, 4096)
yield uwsgi.wait_fd_read(input, 30)
if env['x-wsgiorg.fdevent.timeout']:
print "connection timed out !!!"
uwsgi.close(fd)
raise StopIteration
body = uwsgi.recv(input, bufsize)
if body:
uwsgi.send(fd, body)
cl = cl - len(body)
else:
break
# wait for response (30s timeout)
yield uwsgi.wait_fd_read(fd, 30)
# wait for response (30s timeout)
yield uwsgi.wait_fd_read(fd, 30)
# has timed out ?
if env['x-wsgiorg.fdevent.timeout']:
print "connection timed out !!!"
uwsgi.close(fd)
raise StopIteration
# has timed out ?
if env['x-wsgiorg.fdevent.timeout']:
print "connection timed out !!!"
uwsgi.close(fd)
raise StopIteration
data = uwsgi.recv(fd)
# recv the data, if it returns None the callable will end
while data:
yield data
# wait for response
yield uwsgi.wait_fd_read(fd, 30)
if env['x-wsgiorg.fdevent.timeout']:
print "connection timed out !!!"
uwsgi.close(fd)
raise StopIteration
data = uwsgi.recv(fd)
data = uwsgi.recv(fd)
# recv the data, if it returns None the callable will end
while data:
yield data
# wait for response
yield uwsgi.wait_fd_read(fd, 30)
if env['x-wsgiorg.fdevent.timeout']:
print "connection timed out !!!"
uwsgi.close(fd)
raise StopIteration
data = uwsgi.recv(fd)
uwsgi.close(fd)
uwsgi.close(fd)
+3 -3
View File
@@ -2,7 +2,7 @@
import uwsgi
def application(e, s):
def application(e,s):
for part in uwsgi.send_message("192.168.173.100:3032", 0, 0, e, 0, e['wsgi.input'].fileno(), uwsgi.cl()):
yield part
for part in uwsgi.send_message("192.168.173.100:3032", 0, 0, e, 0, e['wsgi.input'].fileno(), uwsgi.cl()):
yield part
+13 -14
View File
@@ -3,24 +3,23 @@ import uwsgi
current_node = 0
def application(e,s):
def application(e, s):
global current_node
global current_node
nodes = uwsgi.cluster_nodes()
print nodes
nodes = uwsgi.cluster_nodes()
print nodes
if len(nodes) == 0:
print "no cluster node available"
raise StopIteration
if len(nodes) == 0:
print "no cluster node available"
raise StopIteration
if current_node >= len(nodes):
current_node = 0
if current_node >= len(nodes):
current_node = 0
node = nodes[current_node]
node = nodes[current_node]
for part in uwsgi.send_message(node, 0, 0, e, 0, e['wsgi.input'].fileno(), uwsgi.cl()):
yield part
for part in uwsgi.send_message(node, 0, 0, e, 0, e['wsgi.input'].fileno(), uwsgi.cl()):
yield part
current_node += 1
current_node+=1
+8 -9
View File
@@ -1,15 +1,14 @@
import uwsgi
def application(e,s):
def application(e, s):
node = uwsgi.cluster_best_node()
print node
node = uwsgi.cluster_best_node()
print node
if not node:
print "sorry node unavailable"
raise StopIteration
if not node:
print "sorry node unavailable"
raise StopIteration
for part in uwsgi.send_message(node, 0, 0, e, 0, e['wsgi.input'].fileno(), uwsgi.cl()):
yield part
for part in uwsgi.send_message(node, 0, 0, e, 0, e['wsgi.input'].fileno(), uwsgi.cl()):
yield part
+3 -4
View File
@@ -3,8 +3,7 @@ import uwsgi
fd = uwsgi.connect("127.0.0.1:3033")
def application(e,s):
def application(e, s):
for part in uwsgi.send_message(fd, 0, 4, e, 30, e['wsgi.input'].fileno(), uwsgi.cl()):
yield part
for part in uwsgi.send_message(fd, 0, 4, e, 30, e['wsgi.input'].fileno(), uwsgi.cl()):
yield part
+5 -5
View File
@@ -36,7 +36,7 @@ def application(env, start_response):
yield "<h2>Hooks</h2>"
for h in range(0, 255):
for h in range(0,255):
if uwsgi.has_hook(h):
yield "%d<br/>" % h
@@ -45,15 +45,15 @@ def application(env, start_response):
yield '<table border="1">'
yield '<th>worker id</th><th>pid</th><th>in request</th><th>requests</th><th>running time</th><th>address space</th><th>rss</th>'
workers = uwsgi.workers()
workers = uwsgi.workers();
yield '<h2>workers</h2>'
for w in workers:
# print w
# print w['running_time']
#print w
#print w['running_time']
if w is not None:
yield '<tr><td>' + str(w['id']) + '</td><td>' + str(w['pid']) + '</td><td>' + str(w['pid']) + '</td><td>' + str(w['requests']) + '</td><td>' + str(w['running_time']) + '</td><td>' + str(w['vsz']) + '</td><td>' + str(w['rss']) + '</td></tr>'
yield '<tr><td>'+ str(w['id']) +'</td><td>' + str(w['pid']) + '</td><td>' + str(w['pid']) + '</td><td>' + str(w['requests']) + '</td><td>' + str(w['running_time']) + '</td><td>' + str(w['vsz']) + '</td><td>' + str(w['rss']) + '</td></tr>'
print w
yield '</table>'
+11 -13
View File
@@ -2,8 +2,7 @@ import uwsgi
import os
import gc
import sys
from uwsgidecorators import rpc, signal, postfork
from uwsgidecorators import *
print(sys.version)
print(sys.version_info)
if 'set_debug' in gc.__dict__:
@@ -27,7 +26,6 @@ def after_request_hook():
uwsgi.after_req_hook = after_request_hook
@rpc('hello')
def hello_rpc(one, two, three):
arg0 = one[::-1]
@@ -35,24 +33,20 @@ def hello_rpc(one, two, three):
arg2 = three[::-1]
return "!%s-%s-%s!" % (arg1, arg2, arg0)
@signal(17)
def ciao_mondo(signum):
print("Hello World")
def xsendfile(e, sr):
sr('200 OK', [('Content-Type', 'image/png'), ('X-Sendfile', os.path.abspath('logo_uWSGI.png'))])
return ''
def serve_logo(e, sr):
# use raw facilities (status will not be set...)
uwsgi.send("%s 200 OK\r\nContent-Type: image/png\r\n\r\n" % e['SERVER_PROTOCOL'])
uwsgi.sendfile('logo_uWSGI.png')
return ''
def serve_config(e, sr):
sr('200 OK', [('Content-Type', 'text/html')])
for opt in uwsgi.opt.keys():
@@ -63,13 +57,11 @@ routes['/xsendfile'] = xsendfile
routes['/logo'] = serve_logo
routes['/config'] = serve_config
@postfork
def setprocname():
if uwsgi.worker_id() > 0:
uwsgi.setprocname("i am the worker %d" % uwsgi.worker_id())
def application(env, start_response):
try:
uwsgi.mule_msg(env['REQUEST_URI'], 1)
@@ -90,6 +82,7 @@ def application(env, start_response):
if env['PATH_INFO'] in routes:
return routes[env['PATH_INFO']](env, start_response)
if DEBUG:
print(env['wsgi.input'].fileno())
@@ -105,7 +98,7 @@ def application(env, start_response):
for w in uwsgi.workers():
apps = '<table border="1"><tr><th>id</th><th>mountpoint</th><th>startup time</th><th>requests</th></tr>'
for app in w['apps']:
apps += '<tr><td>%d</td><td>%s</td><td>%d</td><td>%d</td></tr>' % (app['id'], app['mountpoint'], app['startup_time'], app['requests'])
apps += '<tr><td>%d</td><td>%s</td><td>%d</td><td>%d</td></tr>' % (app['id'], app['mountpoint'], app['startup_time'], app['requests'])
apps += '</table>'
workers += """
<tr>
@@ -129,9 +122,14 @@ Workers and applications<br/>
%s
</table>
""" % (uwsgi.version, uwsgi.hostname, env.get('REMOTE_USER', 'None'), workers)
""" % (uwsgi.version, uwsgi.hostname, env.get('REMOTE_USER','None'), workers)
start_response('200 OK', [('Content-Type', 'text/html'), ('Content-Length', str(len(output)))])
start_response('200 OK', [('Content-Type', 'text/html'), ('Content-Length', str(len(output)) )])
# return bytes(output.encode('latin1'))
#return bytes(output.encode('latin1'))
return output
+6 -4
View File
@@ -1,17 +1,14 @@
import uwsgi
import os
def xsendfile(e, sr):
sr('200 OK', [('Content-Type', 'image/png'), ('X-Sendfile', os.path.abspath('logo_uWSGI.png'))])
return b''
def serve_logo(e, sr):
sr('200 OK', [('Content-Type', 'image/png')])
return uwsgi.sendfile('logo_uWSGI.png')
def serve_config(e, sr):
sr('200 OK', [('Content-Type', 'text/html')])
for opt in uwsgi.opt.keys():
@@ -23,7 +20,6 @@ routes['/xsendfile'] = xsendfile
routes['/logo'] = serve_logo
routes['/config'] = serve_config
def application(env, start_response):
if env['PATH_INFO'] in routes:
@@ -43,3 +39,9 @@ Configuration<br/>
""".format(version=uwsgi.version.decode('ascii'))
return bytes(body.encode('ascii'))
+1 -1
View File
@@ -1,6 +1,6 @@
require 'net/http'
Net::HTTP.start("uwsgi.it", :use_ssl=>true) do |http|
Net::HTTP.start("uwsgi.it") do |http|
resp = http.get("/install")
open("install.sh", "wb") do |file|
file.write(resp.body)
+4
View File
@@ -179,6 +179,10 @@ char *uwsgi_format_airbrake_backtrace(struct uwsgi_thread *ut) {
}
}
// skip empty lines
if (!p)
goto next;
line_node = xmlNewChild(node, NULL, BAD_CAST "line", NULL);
if ((n+1)[0] == ')') {
+3 -5
View File
@@ -1,11 +1,9 @@
from uwsgiconfig import spcall
NAME = 'airbrake'
NAME='airbrake'
CFLAGS = [spcall('xml2-config --cflags')]
LDFLAGS = []
LIBS = [
'-lcurl',
spcall('xml2-config --libs')
]
LIBS = ['-lcurl', spcall('xml2-config --libs')]
GCC_LIST = ['airbrake_plugin']
+1 -1
View File
@@ -92,7 +92,7 @@ static struct uwsgi_alarm_curl_opt uaco[] = {
static void uwsgi_alarm_curl_setopt(CURL *curl, char *opt, struct uwsgi_alarm_curl_config *uacc) {
struct uwsgi_alarm_curl_opt *o = uaco;
char *equal = strchr(opt,'=');
if (!equal || !uacc->url) {
if (!equal && !uacc->url) {
uwsgi_alarm_curl_url(curl, CURLOPT_URL, opt, uacc);
return;
}
+1 -1
View File
@@ -1,4 +1,4 @@
NAME = 'alarm_curl'
NAME='alarm_curl'
CFLAGS = []
LDFLAGS = []
+1 -1
View File
@@ -1,6 +1,6 @@
import os
NAME = 'alarm_speech'
NAME='alarm_speech'
uwsgi_os = os.uname()[0]
+1 -1
View File
@@ -1,4 +1,4 @@
NAME = 'alarm_xmpp'
NAME='alarm_xmpp'
CFLAGS = []
LDFLAGS = []
+2 -2
View File
@@ -205,7 +205,7 @@ static PyObject *py_uwsgi_asyncio_accept(PyObject *self, PyObject *args) {
// enter harakiri mode
if (uwsgi.harakiri_options.workers > 0) {
set_harakiri(wsgi_req, uwsgi.harakiri_options.workers);
set_harakiri(uwsgi.harakiri_options.workers);
}
uwsgi.async_proto_fd_table[wsgi_req->fd] = wsgi_req;
@@ -312,7 +312,7 @@ static void asyncio_loop() {
uwsgi.wait_write_hook = uwsgi_asyncio_wait_write_hook;
uwsgi.wait_read_hook = uwsgi_asyncio_wait_read_hook;
if (uwsgi.async < 1) {
if (uwsgi.async < 2) {
uwsgi_log("the asyncio loop engine requires async mode (--async <n>)\n");
exit(1);
}
+3 -6
View File
@@ -1,11 +1,8 @@
from distutils import sysconfig
NAME = 'asyncio'
CFLAGS = [
'-I' + sysconfig.get_python_inc(),
'-I' + sysconfig.get_python_inc(plat_specific=True)
]
NAME='asyncio'
CFLAGS = ['-I' + sysconfig.get_python_inc(), '-I' + sysconfig.get_python_inc(plat_specific=True)]
LDFLAGS = []
LIBS = []
GCC_LIST = ['asyncio']
+17 -17
View File
@@ -208,10 +208,10 @@ static int uwsgi_cache_request(struct wsgi_request *wsgi_req) {
switch(wsgi_req->uh->modifier2) {
case 0:
// get
if (wsgi_req->uh->_pktsize > 0) {
value = uwsgi_cache_magic_get(wsgi_req->buffer, wsgi_req->uh->_pktsize, &vallen, NULL, NULL);
if (wsgi_req->uh->pktsize > 0) {
value = uwsgi_cache_magic_get(wsgi_req->buffer, wsgi_req->uh->pktsize, &vallen, NULL, NULL);
if (value) {
wsgi_req->uh->_pktsize = vallen;
wsgi_req->uh->pktsize = vallen;
if (uwsgi_response_write_body_do(wsgi_req, (char *)&wsgi_req->uh, 4)) { free(value) ; return -1;}
uwsgi_response_write_body_do(wsgi_req, value, vallen);
free(value);
@@ -220,10 +220,10 @@ static int uwsgi_cache_request(struct wsgi_request *wsgi_req) {
break;
case 1:
// set
if (wsgi_req->uh->_pktsize > 0) {
if (wsgi_req->uh->pktsize > 0) {
// max 3 items
argc = 3;
if (!uwsgi_parse_array(wsgi_req->buffer, wsgi_req->uh->_pktsize, argv, argvs, &argc)) {
if (!uwsgi_parse_array(wsgi_req->buffer, wsgi_req->uh->pktsize, argv, argvs, &argc)) {
if (argc > 1) {
uwsgi_cache_magic_set(argv[0], argvs[0], argv[1], argvs[1], 0, 0, NULL);
}
@@ -232,30 +232,30 @@ static int uwsgi_cache_request(struct wsgi_request *wsgi_req) {
break;
case 2:
// del
if (wsgi_req->uh->_pktsize > 0) {
uwsgi_cache_magic_del(wsgi_req->buffer, wsgi_req->uh->_pktsize, NULL);
if (wsgi_req->uh->pktsize > 0) {
uwsgi_cache_magic_del(wsgi_req->buffer, wsgi_req->uh->pktsize, NULL);
}
break;
case 3:
case 4:
// dict
if (wsgi_req->uh->_pktsize > 0) {
uwsgi_hooked_parse(wsgi_req->buffer, wsgi_req->uh->_pktsize, cache_simple_command, (void *) wsgi_req);
if (wsgi_req->uh->pktsize > 0) {
uwsgi_hooked_parse(wsgi_req->buffer, wsgi_req->uh->pktsize, cache_simple_command, (void *) wsgi_req);
}
break;
case 5:
// get (uwsgi + stream)
if (wsgi_req->uh->_pktsize > 0) {
value = uwsgi_cache_magic_get(wsgi_req->buffer, wsgi_req->uh->_pktsize, &vallen, NULL, NULL);
if (wsgi_req->uh->pktsize > 0) {
value = uwsgi_cache_magic_get(wsgi_req->buffer, wsgi_req->uh->pktsize, &vallen, NULL, NULL);
if (value) {
wsgi_req->uh->_pktsize = 0;
wsgi_req->uh->pktsize = 0;
wsgi_req->uh->modifier2 = 1;
if (uwsgi_response_write_body_do(wsgi_req, (char *)&wsgi_req->uh, 4)) { free(value) ;return -1;}
uwsgi_response_write_body_do(wsgi_req, value, vallen);
free(value);
}
else {
wsgi_req->uh->_pktsize = 0;
wsgi_req->uh->pktsize = 0;
wsgi_req->uh->modifier2 = 0;
uwsgi_response_write_body_do(wsgi_req, (char *)&wsgi_req->uh, 4);
free(value);
@@ -265,8 +265,8 @@ static int uwsgi_cache_request(struct wsgi_request *wsgi_req) {
case 6:
// dump
uc = uwsgi.caches;
if (wsgi_req->uh->_pktsize > 0) {
uc = uwsgi_cache_by_namelen(wsgi_req->buffer, wsgi_req->uh->_pktsize);
if (wsgi_req->uh->pktsize > 0) {
uc = uwsgi_cache_by_namelen(wsgi_req->buffer, wsgi_req->uh->pktsize);
}
if (!uc) break;
@@ -299,9 +299,9 @@ static int uwsgi_cache_request(struct wsgi_request *wsgi_req) {
uwsgi_buffer_destroy(cache_dump);
break;
case 17:
if (wsgi_req->uh->_pktsize == 0) break;
if (wsgi_req->uh->pktsize == 0) break;
memset(&ucmc, 0, sizeof(struct uwsgi_cache_magic_context));
if (uwsgi_hooked_parse(wsgi_req->buffer, wsgi_req->uh->_pktsize, uwsgi_cache_magic_context_hook, &ucmc)) {
if (uwsgi_hooked_parse(wsgi_req->buffer, wsgi_req->uh->pktsize, uwsgi_cache_magic_context_hook, &ucmc)) {
break;
}
manage_magic_context(wsgi_req, &ucmc);
+1 -1
View File
@@ -1,5 +1,5 @@
NAME = 'cache'
NAME='cache'
CFLAGS = []
LDFLAGS = []
LIBS = []
+2 -1
View File
@@ -1,6 +1,7 @@
NAME = 'carbon'
NAME='carbon'
CFLAGS = []
LDFLAGS = []
LIBS = []
GCC_LIST = ['carbon']
+3 -3
View File
@@ -480,7 +480,7 @@ static int uwsgi_cgi_request(struct wsgi_request *wsgi_req) {
char *script_name = NULL;
/* Standard CGI request */
if (!wsgi_req->len) {
if (!wsgi_req->uh->pktsize) {
uwsgi_log("Empty CGI request. skip.\n");
return -1;
}
@@ -533,9 +533,9 @@ static int uwsgi_cgi_request(struct wsgi_request *wsgi_req) {
memcpy(full_path, tmp_path, full_path_len+1);
if (uwsgi_starts_with(full_path, full_path_len, docroot, docroot_len)) {
uwsgi_log("CGI security error: %s is not under %s\n", full_path, docroot);
if (need_free)
free(docroot);
uwsgi_log("CGI security error: %s is not under %s\n", full_path, docroot);
return -1;
}
@@ -731,7 +731,7 @@ clear2:
// now wait for process exit/death
// in async mode we need a trick...
if (uwsgi.async > 0) {
if (uwsgi.async > 1) {
pid_t diedpid = waitpid(cgi_pid, &waitpid_status, WNOHANG);
if (diedpid < 0) {
uwsgi_error("waitpid()");
+1 -2
View File
@@ -1,5 +1,4 @@
NAME = 'cgi'
NAME='cgi'
CFLAGS = []
LDFLAGS = []
LIBS = []
+1 -1
View File
@@ -1,4 +1,4 @@
NAME = 'cheaper_backlog2'
NAME='cheaper_backlog2'
CFLAGS = []
LDFLAGS = []
+1 -1
View File
@@ -1,4 +1,4 @@
NAME = 'cheaper_busyness'
NAME='cheaper_busyness'
CFLAGS = []
LDFLAGS = []
+1 -1
View File
@@ -1,4 +1,4 @@
NAME = 'clock_monotonic'
NAME='clock_monotonic'
CFLAGS = []
LDFLAGS = []
+1 -1
View File
@@ -1,4 +1,4 @@
NAME = 'clock_realtime'
NAME='clock_realtime'
CFLAGS = []
LDFLAGS = []
+3 -18
View File
@@ -65,7 +65,6 @@ void uwsgi_cr_peer_reset(struct corerouter_peer *peer) {
free(peer->tmp_socket_name);
peer->tmp_socket_name = NULL;
}
cr_del_timeout(peer->session->corerouter, peer);
if (peer->fd != -1) {
@@ -94,9 +93,9 @@ void uwsgi_cr_peer_reset(struct corerouter_peer *peer) {
int uwsgi_cr_peer_del(struct corerouter_peer *peer) {
// first of all check if we need to run a flush procedure
if (peer->flush && !peer->is_flushing) {
peer->is_flushing = 1;
peer->is_flushing = 1;
// on success, suspend the execution
if (peer->flush(peer) > 0) return -1;
if (peer->flush(peer) >= 0) return -1;
}
struct corerouter_peer *prev = peer->prev;
struct corerouter_peer *next = peer->next;
@@ -123,7 +122,6 @@ int uwsgi_cr_peer_del(struct corerouter_peer *peer) {
if (peer->out && peer->out_need_free) {
uwsgi_buffer_destroy(peer->out);
}
free(peer);
return 0;
}
@@ -306,16 +304,6 @@ void corerouter_manage_subscription(char *key, uint16_t keylen, char *val, uint1
usr->notify = val;
usr->notify_len = vallen;
}
else if (!uwsgi_strncmp("algo", 4, key, keylen)) {
usr->algo = uwsgi_subscription_algo_get(val, vallen);
}
else if (!uwsgi_strncmp("backup", 6, key, keylen)) {
usr->backup_level = uwsgi_str_num(val, vallen);
}
else if (!uwsgi_strncmp("proto", 5, key, keylen)) {
usr->proto = val;
usr->proto_len = vallen;
}
}
void corerouter_close_peer(struct uwsgi_corerouter *ucr, struct corerouter_peer *peer) {
@@ -438,7 +426,7 @@ void corerouter_close_session(struct uwsgi_corerouter *ucr, struct corerouter_se
if (ucr->subscriptions && tmp_peer->un && tmp_peer->un->len) {
tmp_peer->un->reference--;
}
if (uwsgi_cr_peer_del(tmp_peer) < 0) return;
if (uwsgi_cr_peer_del(tmp_peer) < 0) return;
}
// could be used to free additional resources
@@ -1076,7 +1064,6 @@ void corerouter_send_stats(struct uwsgi_corerouter *ucr) {
#ifdef UWSGI_SSL
if (uwsgi_stats_keylong_comma(us, "sni_enabled", (unsigned long long) s_slot->sni_enabled)) goto end0;
#endif
if (uwsgi_stats_keyval_comma(us, "algo", uwsgi_subscription_algo_name(s_slot->algo))) goto end0;
if (uwsgi_stats_key(us , "nodes")) goto end0;
if (uwsgi_stats_list_open(us)) goto end0;
@@ -1100,8 +1087,6 @@ void corerouter_send_stats(struct uwsgi_corerouter *ucr) {
if (uwsgi_stats_keylong_comma(us, "cores", (unsigned long long) s_node->cores)) goto end0;
if (uwsgi_stats_keylong_comma(us, "load", (unsigned long long) s_node->load)) goto end0;
if (uwsgi_stats_keylong_comma(us, "weight", (unsigned long long) s_node->weight)) goto end0;
if (uwsgi_stats_keylong_comma(us, "backup", (unsigned long long) s_node->backup_level)) goto end0;
if (uwsgi_stats_keyvaln_comma(us, "proto", &s_node->proto, 1)) goto end0;
if (uwsgi_stats_keylong_comma(us, "wrr", (unsigned long long) s_node->wrr)) goto end0;
if (uwsgi_stats_keylong_comma(us, "ref", (unsigned long long) s_node->reference)) goto end0;
if (uwsgi_stats_keylong_comma(us, "failcnt", (unsigned long long) s_node->failcnt)) goto end0;
+2 -5
View File
@@ -192,13 +192,10 @@ struct corerouter_peer {
int current_timeout;
ssize_t (*flush)(struct corerouter_peer *);
int is_flushing;
// maps 1:1 with subscription proto
char proto;
int is_flushing;
int is_buffering;
int buffering_fd;
int buffering_fd;
};
struct uwsgi_corerouter {
+3 -15
View File
@@ -48,18 +48,12 @@ int uwsgi_cr_map_use_pattern(struct uwsgi_corerouter *ucr, struct corerouter_pee
int uwsgi_cr_map_use_subscription(struct uwsgi_corerouter *ucr, struct corerouter_peer *peer) {
struct uwsgi_subscription_client usc;
usc.fd = peer->session->main_peer->fd;
usc.sockaddr = &peer->session->client_sockaddr;
usc.cookie = NULL;
peer->un = uwsgi_get_subscribe_node(ucr->subscriptions, peer->key, peer->key_len, &usc);
peer->un = uwsgi_get_subscribe_node(ucr->subscriptions, peer->key, peer->key_len);
if (peer->un && peer->un->len) {
peer->instance_address = peer->un->name;
peer->instance_address_len = peer->un->len;
peer->modifier1 = peer->un->modifier1;
peer->modifier2 = peer->un->modifier2;
peer->proto = peer->un->proto;
}
else if (ucr->cheap && !ucr->i_am_cheap && uwsgi_no_subscriptions(ucr->subscriptions)) {
uwsgi_gateway_go_cheap(ucr->name, ucr->queue, &ucr->i_am_cheap);
@@ -75,17 +69,12 @@ int uwsgi_cr_map_use_subscription_dotsplit(struct uwsgi_corerouter *ucr, struct
// max 5 split, reduce DOS attempts
int count = 5;
struct uwsgi_subscription_client usc;
usc.fd = peer->session->main_peer->fd;
usc.sockaddr = &peer->session->client_sockaddr;
usc.cookie = NULL;
split:
if (!count) return 0;
#ifdef UWSGI_DEBUG
uwsgi_log("trying with %.*s\n", name_len, name);
#endif
peer->un = uwsgi_get_subscribe_node(ucr->subscriptions, name, name_len, &usc);
peer->un = uwsgi_get_subscribe_node(ucr->subscriptions, name, name_len);
if (!peer->un) {
char *next = memchr(name+1, '.', name_len-1);
if (next) {
@@ -100,8 +89,7 @@ split:
peer->instance_address = peer->un->name;
peer->instance_address_len = peer->un->len;
peer->modifier1 = peer->un->modifier1;
peer->modifier2 = peer->un->modifier2;
peer->proto = peer->un->proto;
peer->modifier2 = peer->un->modifier2;
}
else if (ucr->cheap && !ucr->i_am_cheap && uwsgi_no_subscriptions(ucr->subscriptions)) {
uwsgi_gateway_go_cheap(ucr->name, ucr->queue, &ucr->i_am_cheap);
+1 -1
View File
@@ -1,5 +1,5 @@
NAME = 'corerouter'
NAME='corerouter'
CFLAGS = []
LDFLAGS = []
LIBS = []
+3 -3
View File
@@ -187,7 +187,7 @@ end:
XS(XS_coroae_sighandler) {
int sigfd = (long) XSANY.any_ptr;
uwsgi_receive_signal(NULL, sigfd, "worker", uwsgi.mywid);
uwsgi_receive_signal(sigfd, "worker", uwsgi.mywid);
}
XS(XS_coroae_acceptor) {
@@ -227,7 +227,7 @@ edge:
// enter harakiri mode
if (uwsgi.harakiri_options.workers > 0) {
set_harakiri(wsgi_req, uwsgi.harakiri_options.workers);
set_harakiri(uwsgi.harakiri_options.workers);
}
@@ -356,7 +356,7 @@ static void coroae_wait_condvar(SV *cv) {
static void coroae_loop() {
if (uwsgi.async < 1) {
if (uwsgi.async < 2) {
if (uwsgi.mywid == 1) {
uwsgi_log("the Coro::AnyEvent loop engine requires async mode (--async <n>)\n");
}
+1 -2
View File
@@ -1,8 +1,6 @@
import os
import sys
NAME = 'coroae'
coroapi = None
search_paths = os.popen('perl -MConfig -e \'print $Config{sitearch}.",".join(",", @INC);\'').read().rstrip().split(',')
@@ -14,6 +12,7 @@ if not coroapi:
print "unable to find the Coro perl module !!!"
sys.exit(1)
NAME='coroae'
CFLAGS = os.popen('perl -MExtUtils::Embed -e ccopts').read().rstrip().split()
CFLAGS += ['-Wno-int-to-pointer-cast', '-Wno-error=format', '-Wno-error=int-to-pointer-cast', '-I%s/Coro' % coroapi]
LDFLAGS = []
+1 -1
View File
@@ -28,7 +28,7 @@ extern "C" int uwsgi_cplusplus_request(struct wsgi_request *wsgi_req) {
FakeClass *fc;
// empty request ?
if (!wsgi_req->len) {
if (!wsgi_req->uh->pktsize) {
uwsgi_log( "Invalid request. skip.\n");
goto clear;
}
+1 -1
View File
@@ -1,4 +1,4 @@
NAME = 'cplusplus'
NAME='cplusplus'
CFLAGS = []
LDFLAGS = []
+1 -1
View File
@@ -1,4 +1,4 @@
NAME = 'curl_cron'
NAME='curl_cron'
CFLAGS = []
LDFLAGS = []
-1
View File
@@ -44,7 +44,6 @@ static void *dumb_loop_run(void *arg1) {
}
}
free(str_core);
return NULL;
}
+2 -2
View File
@@ -1,6 +1,6 @@
NAME = 'dumbloop'
NAME='dumbloop'
CFLAGS = []
LDFLAGS = []
LIBS = []
GCC_LIST = ['dumb']
+2 -1
View File
@@ -1,6 +1,7 @@
NAME = 'dummy'
NAME='dummy'
CFLAGS = []
LDFLAGS = []
LIBS = []
GCC_LIST = ['dummy']

Some files were not shown because too many files have changed in this diff Show More