Commit fc1c3e24 authored by Kirill Smelkov's avatar Kirill Smelkov

*: NULL/nullptr -> nil (C++ only)

Convert C++ part of the project to use nil instead of NULL/nullptr.

We do not convert pyx part yet, because Cython currently does not
understand that nullptr_t has properties of NULL and with e.g. the
following change

    --- a/golang/_context.pyx
    +++ b/golang/_context.pyx
    @@ -116,7 +116,7 @@ cdef cppclass _PyValue (_interface, gobject) nogil:
         __dealloc__():
             with gil:
                 obj = <object>this.pyobj
    -            this.pyobj = NULL
    +            this.pyobj = nil
                 Py_DECREF(obj)

errors as

    Error compiling Cython file:
    ------------------------------------------------------------
    ...
            if __decref():
                del self
        __dealloc__():
            with gil:
                obj = <object>this.pyobj
                this.pyobj = nil
                            ^
    ------------------------------------------------------------

    golang/_context.pyx:119:25: Cannot assign type 'nullptr_t' to 'PyObject *'

https://github.com/cython/cython/issues/3314
parent 60f6db6f
// Copyright (C) 2019 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
// Copyright (C) 2019-2020 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
// it under the terms of the GNU General Public License version 3, or (at your
......@@ -53,9 +53,9 @@ struct _Background final : _Context, object {
}
double deadline() { return INFINITY; }
chan<structZ> done() { return NULL; }
error err() { return NULL; }
interface value(const void *key) { return NULL; }
chan<structZ> done() { return nil; }
error err() { return nil; }
interface value(const void *key) { return nil; }
};
static Context _background = adoptref(static_cast<_Context *>(new _Background()));
......@@ -98,7 +98,7 @@ struct _BaseCtx : _Context, object {
// chan: if context can be canceled on its own
// nil: if context can not be canceled on its own
ctx._done = done;
if (done == NULL) {
if (done == nil) {
if (parentv.size() != 1)
panic("BUG: _BaseCtx: done==nil, but len(parentv) != 1");
}
......@@ -109,7 +109,7 @@ struct _BaseCtx : _Context, object {
chan<structZ> done() {
_BaseCtx& ctx = *this;
if (ctx._done != NULL)
if (ctx._done != nil)
return ctx._done;
return ctx._parentv[0]->done();
}
......@@ -130,10 +130,10 @@ struct _BaseCtx : _Context, object {
for (auto parent : ctx._parentv) {
interface v = parent->value(key);
if (v != NULL)
if (v != nil)
return v;
}
return NULL;
return nil;
}
double deadline() {
......@@ -152,7 +152,7 @@ struct _BaseCtx : _Context, object {
// _cancel cancels ctx and its children.
void _cancel(error err) {
_BaseCtx& ctx = *this;
return ctx._cancelFrom(NULL, err);
return ctx._cancelFrom(nil, err);
}
// _cancelFrom cancels ctx and its children.
......@@ -162,7 +162,7 @@ struct _BaseCtx : _Context, object {
set<refptr<_BaseCtx>> children;
ctx._mu.lock();
if (ctx._err != NULL) {
if (ctx._err != nil) {
ctx._mu.unlock();
return; // already canceled
}
......@@ -171,7 +171,7 @@ struct _BaseCtx : _Context, object {
ctx._children.swap(children);
ctx._mu.unlock();
if (ctx._done != NULL)
if (ctx._done != nil)
ctx._done.close();
// no longer need to propagate cancel from parent after we are canceled
......@@ -180,7 +180,7 @@ struct _BaseCtx : _Context, object {
if (parent == cancelFrom)
continue;
_BaseCtx *_parent = dynamic_cast<_BaseCtx *>(parent._ptr());
if (_parent != NULL) {
if (_parent != nil) {
_parent->_mu.lock();
_parent->_children.erase(bctx);
_parent->_mu.unlock();
......@@ -204,14 +204,14 @@ struct _BaseCtx : _Context, object {
// if parent can never be canceled (e.g. it is background) - we
// don't need to propagate cancel from it.
chan<structZ> pdone = parent->done();
if (pdone == NULL)
if (pdone == nil)
continue;
// parent is cancellable - glue to propagate cancel from it to us
_BaseCtx *_parent = dynamic_cast<_BaseCtx *>(parent._ptr());
if (_parent != NULL) {
if (_parent != nil) {
_parent->_mu.lock();
if (_parent->_err != NULL)
if (_parent->_err != nil)
ctx._cancel(_parent->_err);
else
_parent->_children.insert(bctx);
......@@ -259,7 +259,7 @@ struct _ValueCtx : _BaseCtx {
interface _value;
_ValueCtx(const void *key, interface value, Context parent)
: _BaseCtx(NULL, {parent}) {
: _BaseCtx(nil, {parent}) {
_ValueCtx& ctx = *this;
ctx._key = key;
......@@ -363,7 +363,7 @@ static bool _ready(chan<structZ> ch) {
// _tctxchildren returns context's children, assuming context is instance of _BaseCtx.
set<Context> _tctxchildren(Context ctx) {
_BaseCtx *_bctx = dynamic_cast<_BaseCtx*>(ctx._ptr());
if (_bctx == NULL)
if (_bctx == nil)
panic("context is not instance of golang.context._BaseCtx");
set<Context> children;
......
// Copyright (C) 2019 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
// Copyright (C) 2019-2020 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
// it under the terms of the GNU General Public License version 3, or (at your
......@@ -38,7 +38,7 @@ string _vsprintf(const char *format, va_list argp) {
// based on https://stackoverflow.com/a/26221725/9456786
va_list argp2;
va_copy(argp2, argp);
size_t nchar = ::vsnprintf(NULL, 0, format, argp2);
size_t nchar = ::vsnprintf(nil, 0, format, argp2);
va_end(argp2);
std::unique_ptr<char[]> buf( new char[nchar /*for \0*/+1] );
......
......@@ -412,14 +412,14 @@ class chan {
_chan *_ch;
public:
inline chan() { _ch = NULL; } // nil channel if not explicitly initialized
inline chan() { _ch = nil; } // nil channel if not explicitly initialized
friend chan<T> makechan<T>(unsigned size);
friend chan<T> _wrapchan<T>(_chan *_ch);
inline ~chan() { _chanxdecref(_ch); _ch = NULL; }
inline ~chan() { _chanxdecref(_ch); _ch = nil; }
// = nil
inline chan(nullptr_t) { _ch = NULL; }
inline chan& operator=(nullptr_t) { _chanxdecref(_ch); _ch = NULL; return *this; }
inline chan(nullptr_t) { _ch = nil; }
inline chan& operator=(nullptr_t) { _chanxdecref(_ch); _ch = nil; return *this; }
// copy
inline chan(const chan& from) { _ch = from._ch; _chanxincref(_ch); }
inline chan& operator=(const chan& from) {
......@@ -429,10 +429,10 @@ public:
return *this;
}
// move
inline chan(chan&& from) { _ch = from._ch; from._ch = NULL; }
inline chan(chan&& from) { _ch = from._ch; from._ch = nil; }
inline chan& operator=(chan&& from) {
if (this != &from) {
_chanxdecref(_ch); _ch = from._ch; from._ch = NULL;
_chanxdecref(_ch); _ch = from._ch; from._ch = nil;
}
return *this;
}
......@@ -457,7 +457,7 @@ public:
//
// if pok is provided the case is extended to `[*prx, *pok] = ch.recv_()`
// if both prx and pok are omitted the case is reduced to `ch.recv()`.
[[nodiscard]] inline _selcase recvs(T *prx=NULL, bool *pok=NULL) const {
[[nodiscard]] inline _selcase recvs(T *prx=nil, bool *pok=nil) const {
return _selrecv_(_ch, prx, pok);
}
......@@ -466,8 +466,8 @@ public:
inline unsigned cap() const { return _chancap(_ch); }
// compare wrt nil
inline bool operator==(nullptr_t) const { return (_ch == NULL); }
inline bool operator!=(nullptr_t) const { return (_ch != NULL); }
inline bool operator==(nullptr_t) const { return (_ch == nil); }
inline bool operator!=(nullptr_t) const { return (_ch != nil); }
// compare wrt chan
inline bool operator==(const chan<T>& ch2) const { return (_ch == ch2._ch); }
......@@ -494,7 +494,7 @@ chan<T> makechan(unsigned size) {
}
// _wrapchan<T> wraps raw channel with chan<T>.
// raw channel must be either NULL or its element size must correspond to T.
// raw channel must be either nil or its element size must correspond to T.
LIBGOLANG_API void __wrapchan(_chan *_ch, unsigned elemsize);
template<typename T> static inline
chan<T> _wrapchan(_chan *_ch) {
......@@ -577,36 +577,36 @@ class refptr {
public:
// nil if not explicitly initialized
inline refptr() { _obj = NULL; }
inline refptr() { _obj = nil; }
inline ~refptr() {
if (_obj != NULL) {
if (_obj != nil) {
_obj->decref();
_obj = NULL;
_obj = nil;
}
}
// = nil
inline refptr(nullptr_t) { _obj = NULL; }
inline refptr(nullptr_t) { _obj = nil; }
inline refptr& operator=(nullptr_t) {
if (_obj != NULL)
if (_obj != nil)
_obj->decref();
_obj = NULL;
_obj = nil;
return *this;
}
// copy
inline refptr(const refptr& from) {
_obj = from._obj;
if(_obj != NULL)
if (_obj != nil)
_obj->incref();
}
inline refptr& operator=(const refptr& from) {
if (this != &from) {
if (_obj != NULL)
if (_obj != nil)
_obj->decref();
_obj = from._obj;
if (_obj != NULL)
if (_obj != nil)
_obj->incref();
}
return *this;
......@@ -615,14 +615,14 @@ public:
// move
inline refptr(refptr&& from) {
_obj = from._obj;
from._obj = NULL;
from._obj = nil;
}
inline refptr& operator=(refptr&& from) {
if (this != &from) {
if (_obj != NULL)
if (_obj != nil)
_obj->decref();
_obj = from._obj;
from._obj = NULL;
from._obj = nil;
}
return *this;
}
......@@ -632,8 +632,8 @@ public:
friend refptr<T> newref<T> (T *_obj);
// compare wrt nil
inline bool operator==(nullptr_t) const { return (_obj == NULL); }
inline bool operator!=(nullptr_t) const { return (_obj != NULL); }
inline bool operator==(nullptr_t) const { return (_obj == nil); }
inline bool operator!=(nullptr_t) const { return (_obj != nil); }
// compare wrt refptr
inline bool operator==(const refptr& p2) const { return (_obj == p2._obj); }
......@@ -681,21 +681,21 @@ public:
}
// nil if not explicitly initialized
inline global() { _obj = NULL; }
inline global() { _obj = nil; }
// init from refptr<T>
inline global(const refptr<T>& from) {
_obj = from._obj;
if (_obj != NULL)
if (_obj != nil)
_obj->incref();
}
// = nil
inline global(nullptr_t) { _obj = NULL; }
inline global(nullptr_t) { _obj = nil; }
inline global& operator=(nullptr_t) {
if (_obj != NULL)
if (_obj != nil)
_obj->decref();
_obj = NULL;
_obj = nil;
return *this;
}
......@@ -703,8 +703,8 @@ public:
// move - no need due to refptr<T> cast
// compare wrt nil
inline bool operator==(nullptr_t) const { return (_obj == NULL); }
inline bool operator!=(nullptr_t) const { return (_obj != NULL); }
inline bool operator==(nullptr_t) const { return (_obj == nil); }
inline bool operator!=(nullptr_t) const { return (_obj != nil); }
// compare wrt refptr
inline bool operator==(const refptr<T>& p2) const { return (_obj == p2._obj); }
......@@ -747,7 +747,7 @@ template<typename T>
inline refptr<T> newref(T *_obj) {
refptr<T> p;
p._obj = _obj;
if (_obj != NULL)
if (_obj != nil)
_obj->incref();
return p;
}
......
// Copyright (C) 2018-2019 Nexedi SA and Contributors.
// Copyright (C) 2018-2020 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
......@@ -57,10 +57,11 @@ using std::numeric_limits;
using std::unique_ptr;
using std::vector;
static void *zalloc(size_t size);
// golang::
namespace golang {
static void *zalloc(size_t size);
// ---- panic ----
struct PanicError : exception {
......@@ -79,7 +80,7 @@ struct PanicError : exception {
}
// recover recovers from exception thrown by panic.
// it returns: !NULL - there was panic with that argument. NULL - there was no panic.
// it returns: !nil - there was panic with that argument. nil - there was no panic.
// if another exception was thrown - recover rethrows it.
const char *recover() {
// if PanicError was thrown - recover from it
......@@ -89,7 +90,7 @@ const char *recover() {
return exc.arg;
}
return NULL;
return nil;
}
......@@ -110,11 +111,11 @@ struct Bug : exception {
// ---- runtime ----
// initially NULL to crash if runtime was not initialized
static const _libgolang_runtime_ops *_runtime = NULL;
// initially nil to crash if runtime was not initialized
static const _libgolang_runtime_ops *_runtime = nil;
void _libgolang_init(const _libgolang_runtime_ops *runtime_ops) {
if (_runtime != NULL) // XXX better check atomically
if (_runtime != nil) // XXX better check atomically
panic("libgolang: double init");
_runtime = runtime_ops;
}
......@@ -132,7 +133,7 @@ namespace sync {
// _makesema creates new semaphore.
//
// it always returns !NULL and panics on memory allocation failue.
// it always returns !nil and panics on memory allocation failue.
_sema *_makesema() {
_sema *sema = (_sema *)_runtime->sema_alloc();
if (!sema)
......@@ -161,7 +162,7 @@ Sema::Sema() {
Sema::~Sema() {
Sema *sema = this;
_semafree(sema->_gsema);
sema->_gsema = NULL;
sema->_gsema = nil;
}
void Sema::acquire() {
......@@ -297,7 +298,7 @@ struct _RecvSendWaiting {
list_head in_rxtxq; // in recv or send queue of the channel (_chan._recvq|_sendq -> _)
// recv: on wakeup: sender|closer -> receiver; NULL means "don't copy received value"
// recv: on wakeup: sender|closer -> receiver; nil means "don't copy received value"
// send: ptr-to data to send
void *pdata;
// on wakeup: whether recv/send succeeded (send fails on close)
......@@ -345,12 +346,12 @@ _RecvSendWaiting::_RecvSendWaiting() {
// init initializes waiter to be part of group waiting on ch.
void _RecvSendWaiting::init(_WaitGroup *group, _chan *ch) {
_RecvSendWaiting *w = this;
if (w->group != NULL)
if (w->group != nil)
bug("_RecvSendWaiting: double init");
w->group = group;
w->chan = ch;
INIT_LIST_HEAD(&w->in_rxtxq);
w->pdata = NULL;
w->pdata = nil;
w->ok = false;
w->sel_n = -1;
}
......@@ -365,7 +366,7 @@ void _RecvSendWaiting::wakeup(bool ok) {
_WaitGroup::_WaitGroup() {
_WaitGroup *group = this;
group->_sema.acquire();
group->which = NULL;
group->which = nil;
}
// try_to_win tries to win waiter after it was dequeued from a channel's {_send|_recv}q.
......@@ -376,7 +377,7 @@ bool _WaitGroup::try_to_win(_RecvSendWaiting *waiter) { // -> won
bool won;
group->_mu.lock();
if (group->which != NULL) {
if (group->which != nil) {
won = false;
}
else {
......@@ -403,7 +404,7 @@ void _WaitGroup::wait() {
// notification.
void _WaitGroup::wakeup() {
_WaitGroup *group = this;
if (group->which == NULL)
if (group->which == nil)
bug("wakeup: group.which=nil");
group->_sema.release();
}
......@@ -426,17 +427,17 @@ _RecvSendWaiting *_dequeWaiter(list_head *queue) {
}
}
return NULL;
return nil;
}
// _makechan creates new _chan(elemsize, size).
//
// returned channel has refcnt=1.
// _makechan always returns !NULL and panics on memory allocation failure.
// _makechan always returns !nil and panics on memory allocation failure.
_chan *_makechan(unsigned elemsize, unsigned size) {
_chan *ch;
ch = (_chan *)zalloc(sizeof(_chan) + size*elemsize);
if (ch == NULL)
if (ch == nil)
panic("makechan: alloc failed");
new (ch) _chan(); // init .object, ._mu, ...
......@@ -452,7 +453,7 @@ _chan *_makechan(unsigned elemsize, unsigned size) {
// __wrapchan serves _wrapchan<T>.
void __wrapchan(_chan *ch, unsigned elemsize) {
if (ch == NULL)
if (ch == nil)
return; // nil, no elemsize checking
if (ch->_elemsize != elemsize)
panic("wrapchan: elemsize mismatch");
......@@ -463,7 +464,7 @@ void __wrapchan(_chan *ch, unsigned elemsize) {
//
// it is noop if ch=nil.
void _chanxincref(_chan *ch) {
if (ch == NULL)
if (ch == nil)
return;
ch->incref();
}
......@@ -473,7 +474,7 @@ void _chanxincref(_chan *ch) {
// if refcnt goes to zero, the channel is deallocated.
// it is noop if ch=nil.
void _chanxdecref(_chan *ch) {
if (ch == NULL)
if (ch == nil)
return;
ch->decref();
}
......@@ -509,8 +510,8 @@ void _blockforever();
//
// sizeof(*ptx) must be ch._elemsize.
void _chansend(_chan *ch, const void *ptx) {
if (ch == NULL) // NOTE: cannot do this check in _chan::send
_blockforever(); // (C++ assumes `this` is never NULL and optimizes it out)
if (ch == nil) // NOTE: cannot do this check in _chan::send
_blockforever(); // (C++ assumes `this` is never nil and optimizes it out)
ch->send(ptx);
}
template<> void _chan::_send2</*onstack=*/true> (const void *ptx);
......@@ -540,7 +541,7 @@ template<> void _chan::_send2</*onstack=*/false>(const void *ptx) { _chan *ch =
// ptx stack -> heap (if ptx is on stack) TODO avoid copy if ptx is !onstack
void *ptx_onheap = malloc(ch->_elemsize);
if (ptx_onheap == NULL) {
if (ptx_onheap == nil) {
ch->_mu.unlock();
throw bad_alloc();
}
......@@ -572,9 +573,9 @@ void _chan::__send2(const void *ptx, _WaitGroup *g, _RecvSendWaiting *me) { _ch
// ok is true - if receive was delivered by a successful send.
// ok is false - if receive is due to channel being closed and empty.
//
// sizeof(*prx) must be ch._elemsize | prx=NULL.
// sizeof(*prx) must be ch._elemsize | prx=nil.
bool _chanrecv_(_chan *ch, void *prx) {
if (ch == NULL)
if (ch == nil)
_blockforever();
return ch->recv_(prx);
}
......@@ -603,13 +604,13 @@ template<> bool _chan::_recv2_</*onstack=*/false>(void *prx) { _chan *ch = this
unique_ptr<_WaitGroup> g (new _WaitGroup);
unique_ptr<_RecvSendWaiting> me (new _RecvSendWaiting);
if (prx == NULL)
if (prx == nil)
return __recv2_(prx, g.get(), me.get());
// prx stack -> onheap + copy back (if prx is on stack) TODO avoid copy if prx is !onstack
unsigned ch_elemsize = ch->_elemsize;
void *prx_onheap = malloc(ch_elemsize);
if (prx_onheap == NULL) {
if (prx_onheap == nil) {
ch->_mu.unlock();
throw bad_alloc();
}
......@@ -638,9 +639,9 @@ bool _chan::__recv2_(void *prx, _WaitGroup *g, _RecvSendWaiting *me) { _chan *c
// recv receives from the channel.
//
// if prx != NULL received value is put into *prx.
// if prx != nil received value is put into *prx.
void _chanrecv(_chan *ch, void *prx) {
if (ch == NULL)
if (ch == nil)
_blockforever();
ch->recv(prx);
}
......@@ -667,11 +668,11 @@ bool _chan::_trysend(const void *ptx) { // -> done
// synchronous channel
if (ch->_cap == 0) {
_RecvSendWaiting *recv = _dequeWaiter(&ch->_recvq);
if (recv == NULL)
if (recv == nil)
return false;
ch->_mu.unlock();
if (recv->pdata != NULL)
if (recv->pdata != nil)
memcpy(recv->pdata, ptx, ch->_elemsize);
recv->wakeup(/*ok=*/true);
return true;
......@@ -683,7 +684,7 @@ bool _chan::_trysend(const void *ptx) { // -> done
ch->_dataq_append(ptx);
_RecvSendWaiting *recv = _dequeWaiter(&ch->_recvq);
if (recv != NULL) {
if (recv != nil) {
ch->_dataq_popleft(recv->pdata);
ch->_mu.unlock();
recv->wakeup(/*ok=*/true);
......@@ -702,7 +703,7 @@ bool _chan::_trysend(const void *ptx) { // -> done
// if !done - returns with ._mu still being held.
//
// if !done - (*prx, *pok) are left unmodified.
// if prx=NULL received value is not copied into *prx.
// if prx=nil received value is not copied into *prx.
bool _chan::_tryrecv(void *prx, bool *pok) { // -> done
_chan *ch = this;
......@@ -713,7 +714,7 @@ bool _chan::_tryrecv(void *prx, bool *pok) { // -> done
// wakeup a blocked writer, if there is any
_RecvSendWaiting *send = _dequeWaiter(&ch->_sendq);
if (send != NULL) {
if (send != nil) {
ch->_dataq_append(send->pdata);
ch->_mu.unlock();
send->wakeup(/*ok=*/true);
......@@ -727,7 +728,7 @@ bool _chan::_tryrecv(void *prx, bool *pok) { // -> done
// closed
if (ch->_closed) {
ch->_mu.unlock();
if (prx != NULL)
if (prx != nil)
memset(prx, 0, ch->_elemsize);
*pok = false;
return true;
......@@ -735,11 +736,11 @@ bool _chan::_tryrecv(void *prx, bool *pok) { // -> done
// sync | empty: there is waiting writer
_RecvSendWaiting *send = _dequeWaiter(&ch->_sendq);
if (send == NULL)
if (send == nil)
return false;
ch->_mu.unlock();
if (prx != NULL)
if (prx != nil)
memcpy(prx, send->pdata, ch->_elemsize);
*pok = true;
send->wakeup(/*ok=*/true);
......@@ -748,7 +749,7 @@ bool _chan::_tryrecv(void *prx, bool *pok) { // -> done
// close closes sending side of the channel.
void _chanclose(_chan *ch) {
if (ch == NULL)
if (ch == nil)
panic("close of nil channel");
ch->close();
}
......@@ -768,10 +769,10 @@ void _chan::close() {
// schedule: wake-up all readers
while (1) {
_RecvSendWaiting *recv = _dequeWaiter(&ch->_recvq);
if (recv == NULL)
if (recv == nil)
break;
if (recv->pdata != NULL)
if (recv->pdata != nil)
memset(recv->pdata, 0, ch->_elemsize);
wakeupv.push_back(recv);
}
......@@ -779,7 +780,7 @@ void _chan::close() {
// schedule: wake-up all writers (they will panic)
while (1) {
_RecvSendWaiting *send = _dequeWaiter(&ch->_sendq);
if (send == NULL)
if (send == nil)
break;
wakeupv.push_back(send);
......@@ -793,7 +794,7 @@ void _chan::close() {
// len returns current number of buffered elements.
unsigned _chanlen(_chan *ch) {
if (ch == NULL)
if (ch == nil)
return 0; // len(nil) = 0
return ch->len();
}
......@@ -808,7 +809,7 @@ unsigned _chan::len() {
// cap returns channel capacity.
unsigned _chancap(_chan *ch) {
if (ch == NULL)
if (ch == nil)
return 0; // cap(nil) = 0
return ch->cap();
}
......@@ -834,7 +835,7 @@ void _chan::_dataq_append(const void *ptx) {
// _dataq_popleft pops oldest element from ch._dataq into *prx.
// called with ch._mu locked.
// if prx=NULL the element is popped, but not copied anywhere.
// if prx=nil the element is popped, but not copied anywhere.
void _chan::_dataq_popleft(void *prx) {
_chan *ch = this;
......@@ -843,7 +844,7 @@ void _chan::_dataq_popleft(void *prx) {
if (ch->_dataq_r >= ch->_cap)
bug("chan: dataq.popleft: r >= cap");
if (prx != NULL)
if (prx != nil)
memcpy(prx, &((char *)(ch+1))[ch->_dataq_r * ch->_elemsize], ch->_elemsize);
ch->_dataq_r++; ch->_dataq_r %= ch->_cap;
ch->_dataq_n--;
......@@ -855,13 +856,13 @@ void _chan::_dataq_popleft(void *prx) {
// _default represents default case for _select.
static _selcase _mkdefault() {
_selcase _ = {
.ch = NULL,
.ch = nil,
.op = _DEFAULT,
.flags = (_selflags)0,
.user = 0xff,
};
_ .ptxrx = NULL;
_ .rxok = NULL;
_ .ptxrx = nil;
_ .rxok = nil;
return _;
}
const _selcase _default = _mkdefault();
......@@ -933,7 +934,7 @@ int _chanselect(const _selcase *casev, int casec) {
// send
else if (cas->op == _CHANSEND) {
if (ch != NULL) { // nil chan is never ready
if (ch != nil) { // nil chan is never ready
ch->_mu.lock();
if (1) {
bool done = ch->_trysend(cas->ptx());
......@@ -947,7 +948,7 @@ int _chanselect(const _selcase *casev, int casec) {
// recv
else if (cas->op == _CHANRECV) {
if (ch != NULL) { // nil chan is never ready
if (ch != nil) { // nil chan is never ready
// recv into inplace data is not supported
// ( in the future we might want to support it for symmetry with
// send, but it will requre to drop const from casev )
......@@ -958,7 +959,7 @@ int _chanselect(const _selcase *casev, int casec) {
if (1) {
bool ok, done = ch->_tryrecv(cas->prx(), &ok);
if (done) {
if (cas->rxok != NULL)
if (cas->rxok != nil)
*cas->rxok = ok;
return n;
}
......@@ -1016,7 +1017,7 @@ template<> int _chanselect2</*onstack=*/false>(const _selcase *casev, int casec,
for (i = 0; i < casec; i++) {
const _selcase *cas = &casev[i];
casev_onheap[i] = *cas;
if (cas->ch == NULL) // nil chan
if (cas->ch == nil) // nil chan
continue;
if (cas->op == _CHANSEND) {
if (!(cas->flags & _INPLACE_DATA))
......@@ -1032,7 +1033,7 @@ template<> int _chanselect2</*onstack=*/false>(const _selcase *casev, int casec,
// tx are appended sequentially; all rx go to &rxtxdata[0]
char *rxtxdata = (char *)malloc(max(rxmax, txtotal));
if (rxtxdata == NULL)
if (rxtxdata == nil)
throw bad_alloc();
defer([&]() {
free(rxtxdata);
......@@ -1041,7 +1042,7 @@ template<> int _chanselect2</*onstack=*/false>(const _selcase *casev, int casec,
char *ptx = rxtxdata;
for (i = 0; i <casec; i++) {
_selcase *cas = &casev_onheap[i];
if (cas->ch == NULL) // nil chan
if (cas->ch == nil) // nil chan
continue;
if (cas->op == _CHANSEND) {
if (!(cas->flags & _INPLACE_DATA)) {
......@@ -1066,7 +1067,7 @@ template<> int _chanselect2</*onstack=*/false>(const _selcase *casev, int casec,
_selcase *cas = &casev_onheap[selected];
if (cas->op == _CHANRECV) {
const _selcase *cas0 = &casev[selected];
if (cas0->ptxrx != NULL)
if (cas0->ptxrx != nil)
memcpy(cas0->ptxrx, cas->ptxrx, cas->ch->_elemsize);
}
......@@ -1078,7 +1079,7 @@ static int __chanselect2(const _selcase *casev, int casec, const vector<int>& nv
// XXX or let caller stack-allocate? but then we force it to know sizeof(_RecvSendWaiting)
_RecvSendWaiting *waitv = (_RecvSendWaiting *)calloc(sizeof(_RecvSendWaiting), casec);
int waitc = 0;
if (waitv == NULL)
if (waitv == nil)
throw bad_alloc();
// on exit: remove all registered waiters from their wait queues.
defer([&]() {
......@@ -1091,7 +1092,7 @@ static int __chanselect2(const _selcase *casev, int casec, const vector<int>& nv
bzero((void *)waitv, waitc*sizeof(waitv[0]));
free(waitv);
waitv = NULL;
waitv = nil;
});
......@@ -1099,14 +1100,14 @@ static int __chanselect2(const _selcase *casev, int casec, const vector<int>& nv
const _selcase *cas = &casev[n];
_chan *ch = cas->ch;
if (ch == NULL) // nil chan is never ready
if (ch == nil) // nil chan is never ready
continue;
ch->_mu.lock();
with_lock(g->_mu) { // with, because _trysend may panic
// a case that we previously queued already won while we were
// queuing other cases.
if (g->which != NULL) {
if (g->which != nil) {
ch->_mu.unlock();
goto wait_case_ready;
}
......@@ -1115,7 +1116,7 @@ static int __chanselect2(const _selcase *casev, int casec, const vector<int>& nv
if (cas->op == _CHANSEND) {
bool done = ch->_trysend(cas->ptx());
if (done) {
g->which = &_sel_txrx_prepoll_won; // !NULL not to let already queued cases win
g->which = &_sel_txrx_prepoll_won; // !nil not to let already queued cases win
return n;
}
......@@ -1135,8 +1136,8 @@ static int __chanselect2(const _selcase *casev, int casec, const vector<int>& nv
else if (cas->op == _CHANRECV) {
bool ok, done = ch->_tryrecv(cas->prx(), &ok);
if (done) {
g->which = &_sel_txrx_prepoll_won; // !NULL not to let already queued cases win
if (cas->rxok != NULL)
g->which = &_sel_txrx_prepoll_won; // !nil not to let already queued cases win
if (cas->rxok != nil)
*cas->rxok = ok;
return n;
}
......@@ -1176,7 +1177,7 @@ wait_case_ready:
return selected;
}
else if (cas->op == _CHANRECV) {
if (cas->rxok != NULL)
if (cas->rxok != nil)
*cas->rxok = sel->ok;
return selected;
}
......@@ -1185,9 +1186,9 @@ wait_case_ready:
}
// _blockforever blocks current goroutine forever.
void (*_tblockforever)() = NULL;
void (*_tblockforever)() = nil;
void _blockforever() {
if (_tblockforever != NULL)
if (_tblockforever != nil)
_tblockforever();
// take a lock twice. It will forever block on the second lock attempt.
// Under gevent, similarly to Go, this raises "LoopExit: This operation
......@@ -1261,10 +1262,15 @@ double now() {
// ---- misc ----
// golang::
namespace golang {
// zalloc allocates zeroed memory.
static void *zalloc(size_t size) {
void *mem = malloc(size);
if (mem != NULL)
if (mem != nil)
memset(mem, 0, size);
return mem;
}
} // golang::
// Copyright (C) 2019 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
// Copyright (C) 2019-2020 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
// it under the terms of the GNU General Public License version 3, or (at your
......@@ -46,14 +46,14 @@ using std::vector;
// verify chan<T> automatic reference counting.
void _test_chan_cpp_refcount() {
chan<int> ch;
ASSERT(ch == NULL);
ASSERT(!(ch != NULL));
ASSERT(ch._rawchan() == NULL);
ASSERT(ch == nil);
ASSERT(!(ch != nil));
ASSERT(ch._rawchan() == nil);
ch = makechan<int>();
ASSERT(!(ch == NULL));
ASSERT(ch != NULL);
ASSERT(ch._rawchan() != NULL);
ASSERT(!(ch == nil));
ASSERT(ch != nil);
ASSERT(ch._rawchan() != nil);
_chan *_ch = ch._rawchan();
ASSERT(_chanrefcnt(_ch) == 1);
......@@ -71,8 +71,8 @@ void _test_chan_cpp_refcount() {
// copy =
{
chan<int> ch2;
ASSERT(ch2 == NULL);
ASSERT(ch2._rawchan() == NULL);
ASSERT(ch2 == nil);
ASSERT(ch2._rawchan() == nil);
ch2 = ch;
ASSERT(ch2._rawchan() == _ch);
......@@ -80,9 +80,9 @@ void _test_chan_cpp_refcount() {
ASSERT(ch2 == ch);
ASSERT(!(ch2 != ch));
ch2 = NULL;
ASSERT(ch2 == NULL);
ASSERT(ch2._rawchan() == NULL);
ch2 = nil;
ASSERT(ch2 == nil);
ASSERT(ch2._rawchan() == nil);
ASSERT(_chanrefcnt(_ch) == 1);
ASSERT(!(ch2 == ch));
ASSERT(ch2 != ch);
......@@ -91,18 +91,18 @@ void _test_chan_cpp_refcount() {
// move ctor
chan<int> ch2(move(ch));
ASSERT(ch == NULL);
ASSERT(ch._rawchan() == NULL);
ASSERT(ch2 != NULL);
ASSERT(ch == nil);
ASSERT(ch._rawchan() == nil);
ASSERT(ch2 != nil);
ASSERT(ch2._rawchan() == _ch);
ASSERT(_chanrefcnt(_ch) == 1);
// move =
ch = move(ch2);
ASSERT(ch != NULL);
ASSERT(ch != nil);
ASSERT(ch._rawchan() == _ch);
ASSERT(ch2 == NULL);
ASSERT(ch2._rawchan() == NULL);
ASSERT(ch2 == nil);
ASSERT(ch2._rawchan() == nil);
ASSERT(_chanrefcnt(_ch) == 1);
// ch goes out of scope and destroys raw channel
......@@ -117,7 +117,7 @@ struct Point {
void _test_chan_cpp() {
chan<structZ> done = makechan<structZ>();
chan<int> chi = makechan<int>(1);
chan<Point> chp = makechan<Point>(); chp = NULL;
chan<Point> chp = makechan<Point>(); chp = nil;
int i, j, _;
Point p;
......@@ -155,7 +155,7 @@ void _test_chan_cpp() {
// waitBlocked waits until at least nrx recv and ntx send operations block
// waiting on the channel.
void waitBlocked(_chan *ch, int nrx, int ntx) {
if (ch == NULL)
if (ch == nil)
panic("wait blocked: called on nil channel");
double t0 = time::now();
......@@ -308,12 +308,12 @@ void __test_close_wakeup_all(bool vs_select) {
// as other workers vvv don't use ch after wakeup from ch.recv().
if (!vs_select)
ASSERT(_chanrefcnt(ch._rawchan()) == 1);
ch = NULL;
ch = nil;
done.send(structZ{});
});
waitBlocked(_ch, /*nrx=*/1, /*ntx=*/0);
ASSERT(_chanrefcnt(_ch) == 2);
ch = NULL;
ch = nil;
ASSERT(_chanrefcnt(_ch) == 1);
// many other ch.recv or select({ch.recv}) subscribers queued to ch.recvq
......@@ -321,7 +321,7 @@ void __test_close_wakeup_all(bool vs_select) {
for (i=0; i < N; i++) {
go([_ch, done, vs_select]() {
if (!vs_select) {
_chanrecv(_ch, NULL);
_chanrecv(_ch, nil);
} else {
int rx;
select({
......@@ -363,7 +363,7 @@ void __test_select_win_while_queue() {
Data *data_send = (Data *)calloc(1, sizeof(Data));
Data *data_recv = (Data *)calloc(1, sizeof(Data));
if (data_send == NULL || data_recv == NULL)
if (data_send == nil || data_recv == nil)
throw std::bad_alloc();
for (i=0; i<Ndata; i++)
data_send->_[i] = i % 0xff;
......@@ -407,7 +407,7 @@ void _test_select_inplace() {
// inplace tx
go([ch]() {
_selcase sel[1];
sel[0] = ch.sends(NULL);
sel[0] = ch.sends(nil);
*(int *)&sel[0].itxrx = 12345;
sel[0].flags = _INPLACE_DATA;
int _ = select(sel);
......@@ -421,34 +421,34 @@ void _test_select_inplace() {
_selcase sel[1];
sel[0] = ch.recvs();
sel[0].flags = _INPLACE_DATA;
const char *err = NULL;
const char *err = nil;
try {
select(sel);
} catch (...) {
err = recover();
}
ASSERT(err != NULL);
ASSERT(err != nil);
ASSERT(!strcmp(err, "select: recv into inplace data"));
// _selcase ptx/prx
_selcase cas = _default;
err = NULL;
err = nil;
try {
cas.ptx();
} catch (...) {
err = recover();
}
ASSERT(err != NULL);
ASSERT(err != nil);
ASSERT(!strcmp(err, "_selcase: ptx: op != send"));
err = NULL;
err = nil;
try {
cas.prx();
} catch (...) {
err = recover();
}
ASSERT(err != NULL);
ASSERT(err != nil);
ASSERT(!strcmp(err, "_selcase: prx: op != recv"));
cas = ch.sends(&i);
......@@ -459,13 +459,13 @@ void _test_select_inplace() {
cas = ch.recvs(&i);
ASSERT(cas.prx() == &i);
cas.flags = _INPLACE_DATA;
err = NULL;
err = nil;
try {
cas.prx();
} catch (...) {
err = recover();
}
ASSERT(err != NULL);
ASSERT(err != nil);
ASSERT(!strcmp(err, "_selcase: prx: recv with inplace data"));
}
......@@ -501,9 +501,9 @@ public:
void _test_refptr() {
refptr<MyObj> p;
ASSERT(p == NULL);
ASSERT(!(p != NULL));
ASSERT(p._ptr() == NULL);
ASSERT(p == nil);
ASSERT(!(p != nil));
ASSERT(p._ptr() == nil);
MyObj *obj = new MyObj();
ASSERT(obj->refcnt() == 1);
......@@ -551,8 +551,8 @@ void _test_refptr() {
{
refptr<MyObj> q;
ASSERT(obj->refcnt() == 1);
ASSERT(q == NULL);
ASSERT(q._ptr() == NULL);
ASSERT(q == nil);
ASSERT(q._ptr() == nil);
ASSERT(!(p == q));
ASSERT(p != q);
......@@ -563,10 +563,10 @@ void _test_refptr() {
ASSERT(p == q);
ASSERT(!(p != q));
q = NULL;
q = nil;
ASSERT(obj->refcnt() == 1);
ASSERT(p._ptr() == obj);
ASSERT(q._ptr() == NULL);
ASSERT(q._ptr() == nil);
ASSERT(!(p == q));
ASSERT(p != q);
}
......@@ -575,34 +575,34 @@ void _test_refptr() {
// move ctor
refptr<MyObj> q(move(p));
ASSERT(obj->refcnt() == 1);
ASSERT(p == NULL);
ASSERT(p._ptr() == NULL);
ASSERT(q != NULL);
ASSERT(p == nil);
ASSERT(p._ptr() == nil);
ASSERT(q != nil);
ASSERT(q._ptr() == obj);
// move =
p = move(q);
ASSERT(obj->refcnt() == 1);
ASSERT(p != NULL);
ASSERT(p != nil);
ASSERT(p._ptr() == obj);
ASSERT(q == NULL);
ASSERT(q._ptr() == NULL);
ASSERT(q == nil);
ASSERT(q._ptr() == nil);
// p goes out of scope and destroys obj
}
void _test_global() {
global<refptr<MyObj>> g;
ASSERT(g == NULL);
ASSERT(!(g != NULL));
ASSERT(g._ptr() == NULL);
ASSERT(g == nil);
ASSERT(!(g != nil));
ASSERT(g._ptr() == nil);
MyObj *obj = new MyObj();
refptr<MyObj> p = adoptref(obj);
ASSERT(obj->refcnt() == 1);
obj->i = 3;
ASSERT(g._ptr() == NULL);
ASSERT(g._ptr() == nil);
ASSERT(p._ptr() == obj);
ASSERT(!(g == p));
ASSERT(!(p == g));
......@@ -614,8 +614,8 @@ void _test_global() {
ASSERT(obj->refcnt() == 2);
ASSERT(g._ptr() == obj);
ASSERT(p._ptr() == obj);
ASSERT(!(g == NULL));
ASSERT(g != NULL);
ASSERT(!(g == nil));
ASSERT(g != nil);
ASSERT(g == p);
ASSERT(p == g);
ASSERT(!(g != p));
......@@ -630,15 +630,15 @@ void _test_global() {
// global = nil - obj reference is released
ASSERT(obj->refcnt() == 2);
g = NULL;
g = nil;
ASSERT(obj->refcnt() == 1);
ASSERT(g._ptr() == NULL);
ASSERT(g._ptr() == nil);
// copy ctor global <- refptr
{
global<refptr<MyObj>> h(p);
ASSERT(obj->refcnt() == 2);
ASSERT(g._ptr() == NULL);
ASSERT(g._ptr() == nil);
ASSERT(h._ptr() == obj);
ASSERT(p._ptr() == obj);
ASSERT(!(h == g));
......
// Copyright (C) 2019 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
// Copyright (C) 2019-2020 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
// it under the terms of the GNU General Public License version 3, or (at your
......@@ -39,8 +39,8 @@ namespace runtime {
// pyexited indicates whether Python interpreter exited.
static sync::Mutex *pyexitedMu = NULL; // allocated in _init and never freed not to race
static sync::WaitGroup *pygilTaking = NULL; // at exit on dtor vs use.
static sync::Mutex *pyexitedMu = nil; // allocated in _init and never freed not to race
static sync::WaitGroup *pygilTaking = nil; // at exit on dtor vs use.
static bool pyexited = false;
void _init() {
......@@ -102,8 +102,8 @@ error PyErr_Fetch() {
PyGILState_Release(gstate);
// no error
if (pyexc_type == NULL && pyexc_value == NULL && pyexc_tb == NULL)
return NULL;
if (pyexc_type == nil && pyexc_value == nil && pyexc_tb == nil)
return nil;
// -> _PyError
_PyError* _e = new _PyError();
......@@ -141,9 +141,9 @@ _PyError::~_PyError() {
PyObject *pyexc_type = this->pyexc_type;
PyObject *pyexc_value = this->pyexc_value;
PyObject *pyexc_tb = this->pyexc_tb;
this->pyexc_type = NULL;
this->pyexc_value = NULL;
this->pyexc_tb = NULL;
this->pyexc_type = nil;
this->pyexc_value = nil;
this->pyexc_tb = nil;
if (!ok) {
return;
}
......@@ -182,7 +182,7 @@ PyFunc::PyFunc(const PyFunc& from) {
tie(gstate, ok) = pygil_ensure();
if (!ok) {
pyf = NULL; // won't be used
pyf = nil; // won't be used
return;
}
......@@ -197,7 +197,7 @@ PyFunc::~PyFunc() {
tie(gstate, ok) = pygil_ensure();
PyObject *pyf = this->pyf;
this->pyf = NULL;
this->pyf = nil;
if (!ok) {
return;
}
......@@ -222,8 +222,8 @@ error PyFunc::operator() () const {
}
error err;
PyObject *ret = PyObject_CallFunction(pyf, NULL);
if (ret == NULL) {
PyObject *ret = PyObject_CallFunction(pyf, nil);
if (ret == nil) {
err = PyErr_Fetch();
}
Py_XDECREF(ret);
......
// Copyright (C) 2018-2019 Nexedi SA and Contributors.
// Copyright (C) 2018-2020 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
......@@ -84,13 +84,13 @@ void WaitGroup::add(int delta) {
void WaitGroup::wait() {
WaitGroup& wg = *this;
chan<structZ> done = NULL;
chan<structZ> done = nil;
wg._mu.lock();
if (wg._count != 0)
done = wg._done;
wg._mu.unlock();
if (done == NULL) // wg._count was =0
if (done == nil) // wg._count was =0
return;
done.recv();
......@@ -123,7 +123,7 @@ void _WorkGroup::go(func<error(context::Context)> f) {
});
error err = f(g->_ctx); // TODO consider also propagating panic
if (err == NULL)
if (err == nil)
return;
g->_mu.lock();
......@@ -131,7 +131,7 @@ void _WorkGroup::go(func<error(context::Context)> f) {
g->_mu.unlock();
});
if (g->_err == NULL) {
if (g->_err == nil) {
// this goroutine is the first failed task
g->_err = err;
g->_cancel();
......
// Copyright (C) 2019 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
// Copyright (C) 2019-2020 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com>
//
// This program is free software: you can Use, Study, Modify and Redistribute
// it under the terms of the GNU General Public License version 3, or (at your
......@@ -39,7 +39,7 @@ Timer _new_timer(double dt, func<void()>);
chan<double> tick(double dt) {
if (dt <= 0)
return NULL;
return nil;
return new_ticker(dt)->c;
}
......@@ -120,7 +120,7 @@ void _Timer::decref() {
Timer _new_timer(double dt, func<void()> f) {
Timer t = adoptref(new _Timer());
t->c = (f == NULL ? makechan<double>(1) : NULL);
t->c = (f == nil ? makechan<double>(1) : nil);
t->_f = f;
t->_dt = INFINITY;
t->_ver = 0;
......@@ -129,7 +129,7 @@ Timer _new_timer(double dt, func<void()> f) {
}
Timer new_timer(double dt) {
return _new_timer(dt, NULL);
return _new_timer(dt, nil);
}
bool _Timer::stop() {
......@@ -186,7 +186,7 @@ void _Timer::_fire(double dt, int ver) {
// send under ._mu so that .stop can be sure that if it sees
// ._dt = INFINITY, there is no ongoing .c send.
if (t._f == NULL) {
if (t._f == nil) {
t.c.send(now());
t._mu.unlock();
return;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment