mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-10-04 16:08:31 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d09fd561b6 | ||
|
|
eefaa98cf3 | ||
|
|
ceda8a41e3 | ||
|
|
3021ba3f85 | ||
|
|
3be7312aa8 | ||
|
|
83d782051c | ||
|
|
70996049cc | ||
|
|
e219e209a0 | ||
|
|
eb728cfe23 | ||
|
|
7569544329 | ||
|
|
ee86bf593d | ||
|
|
27ea120325 | ||
|
|
dd21877dcb | ||
|
|
36ca76a231 | ||
|
|
0e339cf968 | ||
|
|
762200fdd6 | ||
|
|
688a464451 | ||
|
|
0dafe8aa5e | ||
|
|
5410cb4fe7 | ||
|
|
86f55a69cf | ||
|
|
6bd59ffe1c | ||
|
|
95a139f73d | ||
|
|
2e71d62704 | ||
|
|
8942e832e9 | ||
|
|
14b0a512e4 | ||
|
|
0c062bbc1a | ||
|
|
c63d94cb6e | ||
|
|
4da7564c3b | ||
|
|
d38edd839e | ||
|
|
cce041c7f0 | ||
|
|
ca68d6938a | ||
|
|
6d700e5a8b | ||
|
|
bad07a8520 | ||
|
|
363b88a7b7 | ||
|
|
932ed8ee29 | ||
|
|
7b8e12911a | ||
|
|
c95062856b | ||
|
|
6840b287d4 | ||
|
|
ae9104ed91 | ||
|
|
6c8d6ea15b | ||
|
|
755eb3956d | ||
|
|
225dc6f7a3 | ||
|
|
8509c41fd6 | ||
|
|
2ae9ac8b88 | ||
|
|
fed00ee5d6 | ||
|
|
66099275ca | ||
|
|
e7a40eb173 | ||
|
|
8342150b78 | ||
|
|
e2253f3693 | ||
|
|
d2f07c7583 | ||
|
|
1c87053a13 | ||
|
|
d69e23414f | ||
|
|
3d37d272ee | ||
|
|
9094a0f811 | ||
|
|
97efcca2b7 | ||
|
|
2445fd1f61 | ||
|
|
3234e0aae8 | ||
|
|
c5e7eb5d95 | ||
|
|
e051e4fe1c | ||
|
|
5f691ec987 | ||
|
|
a8e0aac9b0 | ||
|
|
bcdbab247c | ||
|
|
2e378dfc29 | ||
|
|
acc270ad81 | ||
|
|
b0c3ee02f9 | ||
|
|
06ab5eaee5 | ||
|
|
46de2ae0cb | ||
|
|
65fe93ac14 | ||
|
|
f7cdd22f9a | ||
|
|
3d553d2ae0 | ||
|
|
582d5828aa | ||
|
|
245a66b0e5 | ||
|
|
596c81124e | ||
|
|
a86a1fcc40 | ||
|
|
34036ac8b4 | ||
|
|
11cd6c34a5 | ||
|
|
aaea6ff2e2 | ||
|
|
38c30bc257 | ||
|
|
2f3e83b78e | ||
|
|
43e8c65841 | ||
|
|
555902a0ee | ||
|
|
9d4f4eb3c3 | ||
|
|
5d338cfb3a | ||
|
|
3406441d95 | ||
|
|
df08c7bfb5 | ||
|
|
75b4a3cb28 | ||
|
|
c356c01f12 | ||
|
|
ba8aa44baa | ||
|
|
a1dc7a660c | ||
|
|
3a4663844b | ||
|
|
309f449a43 | ||
|
|
f059a69312 | ||
|
|
93116a1239 | ||
|
|
5e4440443a | ||
|
|
373481b888 | ||
|
|
105b9c69cf | ||
|
|
9012ead72c | ||
|
|
6c1d2625a8 | ||
|
|
c0733b5771 | ||
|
|
f4759d7acd | ||
|
|
7082188a06 | ||
|
|
bcd9ed011d | ||
|
|
25c6d7a3a1 | ||
|
|
675c02c7fa | ||
|
|
32896a1418 | ||
|
|
548e736d84 | ||
|
|
87575b1a22 | ||
|
|
1aa6eeca1b | ||
|
|
f778e30d48 | ||
|
|
e071184d53 | ||
|
|
1d09cde778 | ||
|
|
70ee29becb | ||
|
|
60e26333bf | ||
|
|
865b9c199d | ||
|
|
833193a1ba | ||
|
|
4eab050634 | ||
|
|
688d1d3b75 | ||
|
|
349daee614 | ||
|
|
0d272cf747 | ||
|
|
46ac28efae | ||
|
|
31b3bcc83d | ||
|
|
f364d676fa | ||
|
|
c72fde1eed | ||
|
|
a5cacfbba6 | ||
|
|
921cfa5d79 | ||
|
|
9c676c62f5 | ||
|
|
2917de3e76 | ||
|
|
e836272c07 | ||
|
|
7e25452242 |
@@ -22,7 +22,3 @@ core/dot_h.c
|
||||
+# coverity
|
||||
+/cov-int/
|
||||
+uwsgi.tar.xz
|
||||
|
||||
/build/
|
||||
/dist/
|
||||
/uWSGI.egg-info/
|
||||
|
||||
+5
-4
@@ -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
|
||||
|
||||
|
||||
@@ -29,8 +29,6 @@ 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
@@ -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,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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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, """, 6)) return -1;
|
||||
}
|
||||
else if (buf[i] == '\'') {
|
||||
if (uwsgi_buffer_append(ub, "'", 6)) return -1;
|
||||
}
|
||||
else if (buf[i] == '<') {
|
||||
if (uwsgi_buffer_append(ub, "<", 4)) return -1;
|
||||
}
|
||||
else if (buf[i] == '>') {
|
||||
if (uwsgi_buffer_append(ub, ">", 4)) return -1;
|
||||
}
|
||||
else if (buf[i] == '&') {
|
||||
if (uwsgi_buffer_append(ub, "&", 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
@@ -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
-555
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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) {
|
||||
|
||||
+42
-181
@@ -396,10 +396,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 +407,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, ' ');
|
||||
@@ -639,181 +620,61 @@ void uwsgi_register_base_hooks() {
|
||||
|
||||
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
@@ -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
-47
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -570,7 +570,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
@@ -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
|
||||
|
||||
+6
-21
@@ -291,8 +291,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 +712,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 +748,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 +1212,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 +1511,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 +1550,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
@@ -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
|
||||
|
||||
+15
-27
@@ -176,27 +176,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 +302,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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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
-32
@@ -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;
|
||||
}
|
||||
@@ -1869,32 +1869,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);
|
||||
@@ -1989,10 +1963,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
@@ -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
|
||||
|
||||
+16
-17
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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()");
|
||||
}
|
||||
@@ -1957,7 +1950,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
@@ -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, NULL, 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -514,13 +514,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);
|
||||
|
||||
|
||||
+1
-4
@@ -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,7 +456,7 @@ 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
|
||||
|
||||
+3
-2
@@ -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
@@ -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
@@ -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
+123
-178
@@ -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
|
||||
@@ -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) {
|
||||
@@ -4504,6 +4480,65 @@ mode_t uwsgi_mode_t(char *value, int *error) {
|
||||
return mode;
|
||||
}
|
||||
|
||||
|
||||
int uwsgi_wait_for_mountpoint(char *mountpoint) {
|
||||
if (!uwsgi.wait_for_fs_timeout) {
|
||||
uwsgi.wait_for_fs_timeout = 60;
|
||||
}
|
||||
uwsgi_log("waiting for %s (max %d seconds) ...\n", mountpoint, uwsgi.wait_for_fs_timeout);
|
||||
int counter = 0;
|
||||
for (;;) {
|
||||
if (counter > uwsgi.wait_for_fs_timeout) {
|
||||
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
|
||||
if (!S_ISDIR(st1.st_mode)) 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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
retry:
|
||||
sleep(1);
|
||||
counter++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int uwsgi_wait_for_socket(char *socket_name) {
|
||||
if (!uwsgi.wait_for_socket_timeout) {
|
||||
uwsgi.wait_for_socket_timeout = 60;
|
||||
@@ -4527,93 +4562,3 @@ retry:
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int uwsgi_wait_for_mountpoint(char *mountpoint) {
|
||||
if (!uwsgi.wait_for_fs_timeout) {
|
||||
uwsgi.wait_for_fs_timeout = 60;
|
||||
}
|
||||
uwsgi_log("waiting for %s (max %d seconds) ...\n", mountpoint, uwsgi.wait_for_fs_timeout);
|
||||
int counter = 0;
|
||||
for (;;) {
|
||||
if (counter > uwsgi.wait_for_fs_timeout) {
|
||||
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
|
||||
if (!S_ISDIR(st1.st_mode)) 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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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;
|
||||
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
+25
-167
@@ -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},
|
||||
@@ -214,10 +212,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 +230,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 +250,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 +264,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 +311,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 +342,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 +365,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 +395,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 +413,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},
|
||||
@@ -631,8 +602,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 +668,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 +682,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 +689,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
|
||||
@@ -797,7 +760,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 +767,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 +923,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 +939,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},
|
||||
@@ -1279,7 +1239,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 +1256,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 +1485,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 +1502,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 +1598,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 +1633,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 +1776,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 +2014,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 +2023,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 +2194,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 +2218,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;
|
||||
|
||||
@@ -2368,15 +2284,8 @@ configure:
|
||||
uwsgi_opt_flock(NULL, uwsgi.flock_wait2, NULL);
|
||||
|
||||
// setup master logging
|
||||
if (uwsgi.log_master)
|
||||
if (uwsgi.log_master && !uwsgi.daemonize2)
|
||||
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 +2296,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 +2367,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 +2379,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 +2506,6 @@ configure:
|
||||
#if defined(__linux__) && !defined(__ia64__)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (uwsgi.safe_pidfile && !uwsgi.is_a_reload) {
|
||||
uwsgi_write_pidfile_explicit(uwsgi.safe_pidfile, masterpid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2667,8 +2566,8 @@ int uwsgi_start(void *v_argv) {
|
||||
|
||||
// wait for socket
|
||||
uwsgi_foreach(usl, uwsgi.wait_for_socket) {
|
||||
if (uwsgi_wait_for_socket(usl->value)) exit(1);
|
||||
}
|
||||
if (uwsgi_wait_for_socket(usl->value)) exit(1);
|
||||
}
|
||||
|
||||
if (uwsgi.logto2) {
|
||||
if (!uwsgi.is_a_reload || uwsgi.log_reopen) {
|
||||
@@ -2688,13 +2587,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 +2610,6 @@ int uwsgi_start(void *v_argv) {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __OpenBSD__
|
||||
|
||||
if (uwsgi.rl.rlim_max > 0) {
|
||||
@@ -2794,7 +2688,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 +2942,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 +2996,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 +3176,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,9 +3231,6 @@ next2:
|
||||
}
|
||||
}
|
||||
|
||||
if (uwsgi.safe_pidfile2 && !uwsgi.is_a_reload) {
|
||||
uwsgi_write_pidfile_explicit(uwsgi.safe_pidfile2, masterpid);
|
||||
}
|
||||
|
||||
// END OF INITIALIZATION
|
||||
return 0;
|
||||
@@ -3373,7 +3247,7 @@ void *mem_collector(void *foobar) {
|
||||
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;
|
||||
uint64_t rss, vsz;
|
||||
get_memusage(&rss, &vsz);
|
||||
uwsgi.workers[uwsgi.mywid].rss_size = rss;
|
||||
uwsgi.workers[uwsgi.mywid].vsz_size = vsz;
|
||||
@@ -3515,7 +3389,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 +3533,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 +3764,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 +4024,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 +4055,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)
|
||||
@@ -5032,12 +4896,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
@@ -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
@@ -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,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')
|
||||
|
||||
@@ -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
@@ -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
@@ -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}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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,7 +1,6 @@
|
||||
import uwsgi
|
||||
|
||||
|
||||
def print_logs(ip, port, message):
|
||||
print(ip, port, message)
|
||||
print(ip, port, message)
|
||||
|
||||
uwsgi.udp_callable = print_logs
|
||||
|
||||
@@ -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,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
@@ -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)
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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,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)
|
||||
|
||||
@@ -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] == ')') {
|
||||
|
||||
@@ -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']
|
||||
|
||||
|
||||
@@ -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,4 +1,4 @@
|
||||
NAME = 'alarm_curl'
|
||||
NAME='alarm_curl'
|
||||
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import os
|
||||
|
||||
NAME = 'alarm_speech'
|
||||
NAME='alarm_speech'
|
||||
|
||||
uwsgi_os = os.uname()[0]
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
NAME = 'alarm_xmpp'
|
||||
NAME='alarm_xmpp'
|
||||
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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']
|
||||
|
||||
Vendored
+17
-17
@@ -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);
|
||||
|
||||
Vendored
+1
-1
@@ -1,5 +1,5 @@
|
||||
NAME = 'cache'
|
||||
|
||||
NAME='cache'
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
LIBS = []
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
NAME = 'carbon'
|
||||
|
||||
NAME='carbon'
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
LIBS = []
|
||||
|
||||
GCC_LIST = ['carbon']
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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,5 +1,4 @@
|
||||
NAME = 'cgi'
|
||||
|
||||
NAME='cgi'
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
LIBS = []
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
NAME = 'cheaper_backlog2'
|
||||
NAME='cheaper_backlog2'
|
||||
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
NAME = 'cheaper_busyness'
|
||||
NAME='cheaper_busyness'
|
||||
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
NAME = 'clock_monotonic'
|
||||
NAME='clock_monotonic'
|
||||
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
NAME = 'clock_realtime'
|
||||
NAME='clock_realtime'
|
||||
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,5 +1,5 @@
|
||||
NAME = 'corerouter'
|
||||
|
||||
NAME='corerouter'
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
LIBS = []
|
||||
|
||||
@@ -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,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 = []
|
||||
|
||||
@@ -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,4 +1,4 @@
|
||||
NAME = 'cplusplus'
|
||||
NAME='cplusplus'
|
||||
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
NAME = 'curl_cron'
|
||||
NAME='curl_cron'
|
||||
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
|
||||
@@ -44,7 +44,6 @@ static void *dumb_loop_run(void *arg1) {
|
||||
}
|
||||
}
|
||||
|
||||
free(str_core);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
NAME = 'dumbloop'
|
||||
|
||||
NAME='dumbloop'
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
LIBS = []
|
||||
|
||||
GCC_LIST = ['dumb']
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
NAME = 'dummy'
|
||||
|
||||
NAME='dummy'
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
LIBS = []
|
||||
|
||||
GCC_LIST = ['dummy']
|
||||
|
||||
@@ -4,7 +4,7 @@ extern struct uwsgi_server uwsgi;
|
||||
|
||||
static int uwsgi_echo_request(struct wsgi_request *wsgi_req) {
|
||||
|
||||
return uwsgi_response_write_body_do(wsgi_req, wsgi_req->buffer, wsgi_req->len);
|
||||
return uwsgi_response_write_body_do(wsgi_req, wsgi_req->buffer, wsgi_req->uh->pktsize);
|
||||
}
|
||||
|
||||
struct uwsgi_plugin echo_plugin = {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
NAME = 'echo'
|
||||
NAME='echo'
|
||||
|
||||
CFLAGS = []
|
||||
LDFLAGS = []
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user